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

为什么在全局范围内声明通道会产生死锁问题

为什么在全局范围内声明通道会产生死锁问题

Go
www说 2022-08-24 10:29:09
在3个代码片段中,具有在本地范围声明的通道的代码片段有效,其他代码片段会产生死锁问题,这里前面回答的SO问题之一说尽量避免在全局范围内声明通道。我检查了官方文档,但我没有找到任何解释。为什么全局范围通道在我没有阻止通道发送和接收时出现错误?为什么我在这里遇到死锁问题?在范围和初始化方面与 Except 有何不同?make(chan int)var myChan chan int任何人都可以解释和建议更好的文章/文档/链接/ pdf,以有效地使用Go中的通道(并实现并发)?(为简洁起见,导入和“包主”从片段中省略)// 1. channel declared in global scopevar c chan intfunc main(){    go send()    fmt.Println(<-c)}func send(){    c <- 42}//output: fatal error: all goroutines are asleep - deadlock!// 2. channel declared in global scope + sending channel to goroutinevar c chan intfunc main(){    go send(c)    fmt.Println(<-c)}func send(c chan int){    c <- 42}//output: fatal error: all goroutines are asleep - deadlock!// 3. using channel as local scope and sharing it with goroutinefunc main(){    c := make(chan int)    go send(c)    fmt.Println(<-c)}func send(c chan int){    c <- 42}
查看完整描述

1 回答

?
倚天杖

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

因为通过声明一个未初始化的 ,其类型的零值,在 a 的情况下为 。var c chan intcchannil


如果实际运行代码,错误消息将显示此信息。两个 goroutine 都在 chan 上发送/接收:nil


fatal error: all goroutines are asleep - deadlock!


goroutine 1 [chan receive (nil chan)]:

main.main()

    /tmp/sandbox288806111/prog.go:11 +0x5c


goroutine 18 [chan send (nil chan)]:

main.send()

    /tmp/sandbox288806111/prog.go:15 +0x39

created by main.main

    /tmp/sandbox288806111/prog.go:10 +0x39

相反,您正在显式初始化变量 ,然后不是 。makecnil


这与全局范围本身无关。事实上,如果你正确地初始化变量,例如,即使在全局范围内,程序也不会死锁。var c chan int = make(chan int)


其他读物:通道公理(戴夫·切尼)


如果信道为零,则发送方和接收方没有相互参照;它们都被阻止等待独立频道,并且永远不会取消阻止。


查看完整回答
反对 回复 2022-08-24
  • 1 回答
  • 0 关注
  • 114 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

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

帮助反馈 APP下载

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

公众号

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