英文:
Second channel causing deadlock even if independent
问题
这是一个关于添加第二个通道(在我的例子中是c2)为什么会导致死锁的后续问题。通道是独立的,我不明白为什么c2会被阻塞。
func do_stuff(done chan bool) {
fmt.Println("Doing stuff")
done <- true
}
func main() {
fmt.Println("Main")
done := make(chan bool)
go do_stuff(done)
<-done
// 到这里一切正常
c2 := make(chan int)
c2 <- 1
fmt.Println("Exit ", <-c2)
}
英文:
This is more a follow up question from this other post
I do not understand why adding a second channel (c2 in my case) will cause a deadlock. Channels are independent and I don't see why c2 is supposed to be blocked
func do_stuff(done chan bool) {
fmt.Println("Doing stuff")
done <- true
}
func main() {
fmt.Println("Main")
done := make(chan bool)
go do_stuff(done)
<-done
//Up tp here everything works
c2 := make(chan int)
c2 <- 1
fmt.Println("Exit ",<-c2)
}
答案1
得分: 4
《Go编程语言规范》
发送语句
发送操作会阻塞,直到可以进行发送。如果一个无缓冲通道上的接收方准备好了,发送操作就可以进行。
没有接收方准备好。
package main
func main() {
c2 := make(chan int)
c2 <- 1
}
输出:
致命错误:所有的goroutine都处于休眠状态 - 死锁!
英文:
> The Go Programming Language Specification
>
> Send statements
>
> Communication blocks until the send can proceed. A send on an
> unbuffered channel can proceed if a receiver is ready.
No receiver is ready.
package main
func main() {
c2 := make(chan int)
c2 <- 1
}
Output:
fatal error: all goroutines are asleep - deadlock!
答案2
得分: 2
这些语句
c2 := make(chan int)
c2 <- 1
将会一直阻塞。Playground链接。
因为通道 c2
是无缓冲的,发送操作无法继续进行,直到另一个goroutine从通道中接收到值。由于没有goroutine可以从通道中接收值,因此发送操作将永远阻塞。
在Effective Go的通道部分可以了解更多关于无缓冲通道的内容。还可以参考Go语言规范中关于通道和发送操作的部分。
如果将 c2
改为带缓冲的通道,程序将按照你期望的方式工作:
c2 := make(chan int, 1)
通过这个改变,发送操作可以在没有接收者的情况下继续进行。
英文:
The statements
c2 := make(chan int)
c2 <- 1
will always block. Link to Playground.
Because the channel c2
is unbuffered, the send operation cannot proceed until another goroutine has received the value from the channel. There is no goroutine that can receive from the channel, therefore the send blocks forever.
The channels section in Effective Go is a good place to read about unbuffered channels. Also see the sections on channels and send in the Go Language Specification.
The program will work as I think you are expecting if you make c2
a buffered channel:
c2 := make(chan int, 1)
With this change, the send can proceed without synchronizing with a receiver.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论