英文:
Non-blocking channel operations in go. Send?
问题
我正在阅读《Go by Example: Non-Blocking Channel Operations》。
据我理解,第一个 select
触发了 default
分支,因为 messages
通道中没有任何内容,如果没有 default
分支,我们将会收到一个 fatal error: all goroutines are asleep - deadlock!
错误,对吗?
嗯,我无法理解如何触发第二个 select
,具体来说是触发 case messages <- msg:
。
我认为,它应该与接收操作相反。所以,如果通道中有2个消息的缓冲区,并且我们将第3个消息发送到通道中,它将触发 default
分支,但是 messages
通道是空的,那么为什么在第二个 select
中会触发 default
分支?我如何触发 case messages <- msg:
分支?
英文:
I'm going through Go by Example: Non-Blocking Channel Operations
As far as I understand, the first select
is triggering the default
case because there are nothing in the messages
channel, and if the default
case didn't exist, we would receive a fatal error: all goroutines are asleep - deadlock!
error, right?
Well, I cannot figure out how can I trigger the second select
, specifically trigger the case messages <- msg:
As I thought, it should work opposite to the receive. So if there's a buffer for 2 messages and we send the 3rd message to the channel, it would trigger the default
clause, but the messages
channel is empty, so why in the second select does it trigger the default
clause? And how can I trigger the case messages <- msg:
clause?
答案1
得分: 9
为什么在第二个选择语句中会触发默认子句?
因为该通道是无缓冲的,并且没有其他的Go协程被阻塞在接收操作上。
如何触发case messages <- msg:
子句?
你可以选择以下两种方式:
-
将
messages
通道改为带缓冲的通道messages := make(chan string, 1)
https://play.golang.org/p/b1aO6N-dYf
-
创建另一个被阻塞在接收操作上的Go协程
go func() { fmt.Println("Received from other go routine", <-messages) }()
英文:
> why in the second select does it trigger the default clause?
Because the channel is unbuffered and there is no other go routine blocked on receiving.
> how can I trigger the case messages <- msg: clause?
You can either:
-
Make
messages
bufferedmessages := make(chan string, 1)
https://play.golang.org/p/b1aO6N-dYf
-
Create another go routine that is blocked on receiving
go func() { fmt.Println("Received from other go routine", <-messages) }()
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论