Go语言中的非阻塞通道操作。发送?

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

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 &lt;- 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 &lt;- msg: clause?

答案1

得分: 9

为什么在第二个选择语句中会触发默认子句?

因为该通道是无缓冲的,并且没有其他的Go协程被阻塞在接收操作上。

如何触发case messages <- msg:子句?

你可以选择以下两种方式:

  1. messages通道改为带缓冲的通道

     messages := make(chan string, 1)
    

https://play.golang.org/p/b1aO6N-dYf

  1. 创建另一个被阻塞在接收操作上的Go协程

     go func() {
         fmt.Println("Received from other go routine", <-messages)
     }()
    

    https://play.golang.org/p/Z7e1ZcO3C5

英文:

> 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:

  1. Make messages buffered

     messages := make(chan string, 1)
    

https://play.golang.org/p/b1aO6N-dYf

  1. Create another go routine that is blocked on receiving

     go func() {
         fmt.Println(&quot;Received from other go routine&quot;, &lt;-messages)
     }()
    

    https://play.golang.org/p/Z7e1ZcO3C5

huangapple
  • 本文由 发表于 2016年12月7日 00:25:13
  • 转载请务必保留本文链接:https://go.coder-hub.com/41000161.html
匿名

发表评论

匿名网友

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

确定