英文:
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("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
}
}
If the calling function sends to first channel twice and then to second channel everything works fine:
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
The console output (correctly) is:
> 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.
However, if I comment the second request like
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
Then the output is
> Waiting for select statement ...
> I got a request: {Login yaylaswiese}
> Waiting for select statement ...
> 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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论