重用 Go 通道会导致死锁。

huangapple go评论79阅读模式
英文:

Reusing a Go channel causes deadlock

问题

这段代码中发生了死锁。死锁发生在main函数的第12行,也就是x, y := <-c, <-c这一行。在这行代码中,程序试图从通道c中接收两个值,但是在这个时刻,没有其他的goroutine在向通道c发送值,因此程序无法继续执行,导致了死锁。要解决这个问题,你可以在main函数中的go sendenum(0, c)语句之后再添加一个相同的语句,以确保有足够的goroutine向通道发送值。

英文:

I'm new to golang (whith Java concurrency background). Consider this peace of code :

package main

import &quot;fmt&quot;

func sendenum(num int, c chan int) {
	c &lt;- num
}

func main() {
	c := make(chan int)
	go sendenum(0, c)
	x, y := &lt;-c, &lt;-c
	fmt.Println(x, y)
}

When I run this code , I get this error

fatal error: all goroutines are asleep - deadlock!

goroutine 1 [chan receive]:
main.main()
	/home/tarrsalah/src/go/src/github.com/tarrsalah/stackoverflow/chan_dead_lock.go:12 +0x90
exit status 2

I know, adding another go sendenum(0, c) statement fix the issue, ... but

When and Where the deadlock happened ?

答案1

得分: 5

在收到0之后,main函数会继续等待在通道c的接收端等待另一个值的到来(放入y变量中),但是它永远不会到来,因为运行main函数的goroutine是唯一剩下的活动goroutine。

当你添加另一个go sendenum(0, c)时,它实际上在第二次通道接收时得到一个值,将其放入y变量中,然后打印出xy,程序成功结束。

英文:

After it receives the 0, main keeps on waiting on the receiving end of c for another value to arrive (to put in the y variable), but it never will, as the goroutine running main is the only one left to live.

When you add another go sendenum(0, c), it actually gets a value on the second channel receive, puts it into the y variable, prints x and y out and the program finishes succesfully.

答案2

得分: 0

这不是“重复使用”通道的问题。只是因为代码规定了两次读取,但只有一次写入相同的通道,所以发生了简单的死锁。第二次读取永远不会发生,因此导致了死锁。

英文:

It's not that "reusing" a channel is a problem. It's just a simple deadlock happening because the code prescribes two reads, but only one write to the same channel. The second read can never happen, hence the deadlock.

huangapple
  • 本文由 发表于 2013年9月5日 02:27:41
  • 转载请务必保留本文链接:https://go.coder-hub.com/18621209.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定