第二个通道即使是独立的也会导致死锁。

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

Second channel causing deadlock even if independent

问题

这是一个关于添加第二个通道(在我的例子中是c2)为什么会导致死锁的后续问题。通道是独立的,我不明白为什么c2会被阻塞。

Playground链接

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

Link to playground

func do_stuff(done chan bool) {
	fmt.Println(&quot;Doing stuff&quot;)
	done &lt;- true
}

func main() {
	fmt.Println(&quot;Main&quot;)
	done := make(chan bool)
	go do_stuff(done)
	&lt;-done
    //Up tp here everything works
	c2 := make(chan int)
	c2 &lt;- 1
	fmt.Println(&quot;Exit &quot;,&lt;-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 &lt;- 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)

通过这个改变,发送操作可以在没有接收者的情况下继续进行。

Playground链接

英文:

The statements

c2 := make(chan int)
c2 &lt;- 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.

Link to Playground

huangapple
  • 本文由 发表于 2014年9月22日 10:50:28
  • 转载请务必保留本文链接:https://go.coder-hub.com/25966058.html
匿名

发表评论

匿名网友

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

确定