登录
首页 >  Golang >  Go问答

全局范围内声明通道为何会引发死锁问题?

来源:stackoverflow

时间:2024-02-14 13:18:23 194浏览 收藏

怎么入门Golang编程?需要学习哪些知识点?这是新手们刚接触编程时常见的问题;下面golang学习网就来给大家整理分享一些知识点,希望能够给初学者一些帮助。本篇文章就来介绍《全局范围内声明通道为何会引发死锁问题?》,涉及到,有需要的可以收藏一下

问题内容

在 3 个代码片段中,在本地作用域中声明通道的代码片段有效,其他代码片段会出现死锁问题,此处之前回答的 so 问题之一表示尝试避免在全局作用域中声明通道。我查了官方文档,没有找到任何解释。

  1. 尽管我没有阻止通道发送和接收,但为什么全局范围通道会出错?为什么我在这里遇到死锁问题?

  2. 除了范围和初始化方面之外,make(chan int)var mychan chan int 有何不同?

  3. 任何人都可以解释并建议更好的文章/文档/链接/pdf,以在 go 中有效使用通道(并实现并发)吗?

(为了简洁起见,代码片段中省略了导入和“package main”)

// 1. channel declared in global scope
var c chan int
func 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 goroutine
var c chan int
func 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 goroutine
func main(){
    c := make(chan int)
    go send(c)
    fmt.Println(<-c)
}
func send(c chan int){
    c <- 42
}

解决方案


因为通过声明未初始化的 var c chan intc 的类型值为零,在 chan 的情况下为 nil

如果您确实拨打了 run your code,则错误消息会显示此信息。两个 goroutine 都在 nil chan 上发送/接收:

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

使用 make,您可以显式初始化变量 c,而不是 nil

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

补充阅读:channel axioms (Dave Cheney)

如果通道为零,则发送方和接收方没有相互引用;它们都在独立通道上被阻塞等待,并且永远不会解锁。

今天关于《全局范围内声明通道为何会引发死锁问题?》的内容介绍就到此结束,如果有什么疑问或者建议,可以在golang学习网公众号下多多回复交流;文中若有不正之处,也希望回复留言以告知!

声明:本文转载于:stackoverflow 如有侵犯,请联系study_golang@163.com删除
相关阅读
更多>
最新阅读
更多>
课程推荐
更多>