首页 > 解决方案 > 具有通道参数的函数中的死锁

问题描述

给定以下简单的 Go 程序:

ch := make(chan int)
go fmt.Println(<- ch)
ch <- 2

如果我替换go fmt.Println(<- ch)go func(){fmt.Println(<-ch)}(),则效果很好。

但是对于原始版本,我得到:

fatal error: all goroutines are asleep - deadlock!

为什么?

标签: gochannelgoroutine

解决方案


规范中所定义:

函数值和参数在调用 goroutine 中像往常一样被评估,但与常规调用不同,程序执行不会等待调用的函数完成。相反,该函数开始在一个新的 goroutine 中独立执行。当函数终止时,它的 goroutine 也会终止。如果函数有任何返回值,它们会在函数完成时被丢弃。

所以<-ch被评估了。但它不能,因为通道是空的,因此它会阻塞,直到有东西写入它。但是没有任何东西写入它,因此这是一个死锁。

当您将它包装在匿名函数中时 - 会发生同样的情况,但对于匿名函数。然后它的主体被同时评估到主 goroutine。


推荐阅读