golang:select语句中的通道有时只接收到数据(???)

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

golang: channel in select statement is only receiving sometimes (???)

问题

我在一个Go协程中有一个select语句,从两个通道接收数据。

for {
    fmt.Printf("Waiting for select statement ...\n")
    select {
    case req := <-requestChan:
        fmt.Printf("I got a request: %v\n", req)
    case <-doneChan:
        fmt.Printf("serveDatabase: Got closing signal. Stop serving.\n")
        return
    }
}

如果调用函数先向第一个通道发送两次数据,然后再向第二个通道发送数据,一切都正常:

requestChan <- Db_request{ request: "Login", beehive: "yaylaswiese" }
requestChan <- Db_request{ request: "Signup", beehive: "aziz nezir" }

fmt.Printf("Sending true to the doneChannel\n")
doneChan <- true

控制台输出(正确)为:

>     Waiting for select statement ...
>     I got a request: {Login yaylaswiese}
>     Waiting for select statement ...
>     Sending true to the doneChannel
>     I got a request: {Signup aziz nezir}
>     Waiting for select statement ...
>     serveDatabase: Got closing signal. Stop serving.

然而,如果我注释掉第二个请求:

requestChan <- Db_request{ request: "Login", beehive: "yaylaswiese" }
// requestChan <- Db_request{ request: "Signup", beehive: "aziz nezir" }

fmt.Printf("Sending true to the doneChannel\n")
doneChan <- true

那么输出就是:

>     Waiting for select statement ...
>     I got a request: {Login yaylaswiese}
>     Waiting for select statement ...
>     Sending true to the doneChannel

所以doneChan永远不会被接收。我还尝试在发送doneChan后进入一个无限循环,但结果是一样的。

这可能是什么原因呢?

英文:

I have a select statement in a go routine that receives from two channels.

for {
    fmt.Printf(&quot;Waiting for select statement ...\n&quot;)
    select {
    case req := &lt;-requestChan:
        fmt.Printf(&quot;I got a request: %v\n&quot;, req)
    case &lt;-doneChan:
        fmt.Printf(&quot;serveDatabase: Got closing signal. Stop serving.\n&quot;)
        return
    }
}

If the calling function sends to first channel twice and then to second channel everything works fine:

requestChan &lt;- Db_request{ request: &quot;Login&quot;, beehive: &quot;yaylaswiese&quot; }
requestChan &lt;- Db_request{ request: &quot;Signup&quot;, beehive: &quot;aziz nezir&quot; }

fmt.Printf(&quot;Sending true to the doneChannel\n&quot;)
doneChan &lt;- true

The console output (correctly) is:

&gt;     Waiting for select statement ...
&gt;     I got a request: {Login yaylaswiese}
&gt;     Waiting for select statement ...
&gt;     Sending true to the doneChannel
&gt;     I got a request: {Signup aziz nezir}
&gt;     Waiting for select statement ...
&gt;     serveDatabase: Got closing signal. Stop serving.

However, if I comment the second request like

requestChan &lt;- Db_request{ request: &quot;Login&quot;, beehive: &quot;yaylaswiese&quot; }
// requestChan &lt;- Db_request{ request: &quot;Signup&quot;, beehive: &quot;aziz nezir&quot; }

fmt.Printf(&quot;Sending true to the doneChannel\n&quot;)
doneChan &lt;- true

Then the output is

&gt;     Waiting for select statement ...
&gt;     I got a request: {Login yaylaswiese}
&gt;     Waiting for select statement ...
&gt;     Sending true to the doneChannel

So the doneChan is never received. I tried also to go into a endless loop after sending doneChan, but it has the same result.

What could that be?

答案1

得分: 2

很可能是你的main在其他goroutine完成之前退出了。请注意它们是并发执行的,一旦main完成,所有其他的goroutine都会被终止。

你需要显式地将goroutine的结束与main同步。你可以使用sync.WaitGroup来实现,或者使用另一个通道。

英文:

Most likely, your main is exiting before the other goroutine finalised. Note that they're concurrent, and once main finishes, all other goroutines are killed.

You need to explicitly synchronize the end of your goroutines with main. You can use sync.WaitGroup for that, or another channel.

huangapple
  • 本文由 发表于 2015年1月17日 21:12:18
  • 转载请务必保留本文链接:https://go.coder-hub.com/27999795.html
匿名

发表评论

匿名网友

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

确定