在通道上使用Go例程时出现问题。代码如下:
func main() {
c := make(chan int)
var wg sync.WaitGroup
wg.Add(1)
go func (c chan int, x int) {
c <- x
fmt.Println(x)
close(c)
defer wg.Done()
}(c,10)
wg.Wait()
}
运行代码时出现此错误:
fatal error: all goroutines are asleep - deadlock!
我不明白为什么会发生此问题。请帮助我理解
答案 0 :(得分:3)
在您的示例中,您有2个goroutine:运行main()
函数的主goroutine,另一个在其中运行的goroutine。主goroutine等待另一个goroutine完成(调用wg.Done()
),而其他goroutine则在尝试在通道c
上发送值的行中阻塞。由于没有人从该通道接收消息,并且由于该通道没有缓冲,因此该goroutine将永远不会前进,因此您所有的2个goroutine将永远阻塞。
请注意,defer wg.Done()
应该是goroutine中的第一条语句。如果是最后一个,defer
不会有任何改变。
如果通道的缓冲区至少为1,则发送操作可以继续:
c := make(chan int, 1)
输出将是(在Go Playground上尝试):
10
如果我们不缓冲通道,则必须有另一个从该通道接收的goroutine,例如:
wg.Add(1)
go func() {
defer wg.Done()
x := <-c
fmt.Println("Received:", x)
}()
然后将输出(在Go Playground上尝试):
10
Received: 10