为了账号安全,请及时绑定邮箱和手机立即绑定

golang所有goroutines都睡着了 - 死锁

golang所有goroutines都睡着了 - 死锁

Go
一只甜甜圈 2022-05-23 17:32:04
运行跟随 golang 片段时出现错误。我认为进度将在 wg.Wait() 处阻塞,直到 go 例程结束。那么该值将从 c1 获得。但它可能不会按预期进行。func main() {c1 := make(chan string)//var c1 chan stringvar wg sync.WaitGroupwg.Add(1)go func() {    defer wg.Done()    fmt.Printf("go routine begin\n")    time.Sleep(1 * time.Second)    c1 <- "one"    fmt.Printf("go routine done\n")}()wg.Wait()fmt.Printf("done c1: %v\n", <-c1)fmt.Printf("out\n")}错误信息是, go routine begin fatal error: all goroutines are asleep - deadlock!
查看完整描述

3 回答

?
心有法竹

TA贡献1866条经验 获得超5个赞

写入c1永远不会执行,因为读取c1是在之后wg.Wait(),它将停止直到c1被写入。所以 main goroutine 等待,wg.Wait()嵌套 goroutine 等待c1write。

c1您可以使通道缓冲,或在单独的 goroutine 上等待读取。


查看完整回答
反对 回复 2022-05-23
?
HUWWW

TA贡献1874条经验 获得超12个赞

在 Golang 中,无缓冲通道上的写操作是阻塞的。从文档中可以清楚地看到。

您的执行被阻止在

c1 <- "one"

延期声明

defer wg.Done()

从不执行。


查看完整回答
反对 回复 2022-05-23
?
米脂

TA贡献1836条经验 获得超3个赞

在您的代码中,您正在使用一个无缓冲的通道,该通道会阻塞直到接收器接收到“一个”。在这种情况下,代码不会超过 wg.Wait() 因为 wg.Done() 永远不会被执行。


我想这就是你所追求的。


func main() {


c1 := make(chan string)

//var c1 chan string


go func() {

    fmt.Printf("go routine begin\n")

    time.Sleep(1 * time.Second)

    c1 <- "one"

    fmt.Printf("go routine done\n")

}()

fmt.Printf("done c1: %v\n", <-c1)

fmt.Printf("out\n")

}


查看完整回答
反对 回复 2022-05-23
  • 3 回答
  • 0 关注
  • 154 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号