英文:
Why does this golang program hang in playground when using for loop with select?
问题
考虑以下playground
messages := make(chan int, 1)
done := make(chan bool)
go func() {
for {
select {
case msg := <-messages:
fmt.Println("接收器一", msg)
case signal := <-done:
fmt.Println(signal)
return
default:
fmt.Println("未接收到消息")
}
}
}()
go func() {
for {
select {
case msg := <-messages:
fmt.Println("接收器二", msg)
case signal := <-done:
fmt.Println(signal)
return
default:
fmt.Println("未接收到消息")
}
}
}()
go func() {
for i := 0; i < 2; i++ {
messages <- i
}
done <- true
done <- true
done <- true
}()
<-done
我试图模拟从一个线程向另外两个线程进行通信,但是在playground中上述代码似乎无法正常运行。
有没有什么技巧可以使程序正常工作?
英文:
Consider this playground
messages := make(chan int, 1)
done := make(chan bool)
go func() {
for {
select {
case msg := <- messages:
fmt.Println("receiver one", msg)
case signal := <-done :
fmt.Println(signal)
return
default:
fmt.Println("no message received")
}
}
}()
go func() {
for {
select {
case msg := <- messages:
fmt.Println("receiver two", msg)
case signal := <-done :
fmt.Println(signal)
return
default:
fmt.Println("no message received")
}
}
}()
go func() {
for i := 0; i < 2; i++ {
messages<-i
}
done<-true
done<-true
done<-true
}()
<-done
I am trying to simulate communicate from one thread to two other thread, but it seems like the above code is running fine in my local but not in playground.
Is there a trick to make the program work?
答案1
得分: 2
你应该从select
语句中删除default
子句。
由于你的select
语句位于for
循环内部,并且default
子句会阻止它阻塞,所以循环必须经过很多次迭代才能接收到任何消息。
看起来Playground检测到这个问题并停止了程序。
英文:
You should remove the default
clauses from the select
statements.
Since your select
statement is within a for
loop and the default
clause prevents it from blocking, the loop has to go through a lot of cycles before any message will be received.
Looks like Playground detects it and stops the program.
答案2
得分: 1
如@dev.bmax已经提到的,你错误地使用了default
关键字。
请查看这篇关于使用default
关键字的小文章。
另外,尝试在程序开头添加runtime.GOMAXPROCS(4)
,运行几次并检查输出,看看它的工作方式:
https://play.golang.org/p/TLDHNg6urB
这是一个正确的示例供你参考:
https://play.golang.org/p/bc0TGdmx1Y
请注意,在这种情况下,你应该为停止额外的和主要的goroutine使用不同的通道。
英文:
As @dev.bmax already mentioned, you use default
in a wrong way.
Check this small article about using default
keyword.
Also, try to add runtime.GOMAXPROCS(4)
on the beginning of your program, run few times and check output to see, how it's working:
https://play.golang.org/p/TLDHNg6urB
Here's correct example for you:
https://play.golang.org/p/bc0TGdmx1Y
Note, that in this case you should use different channels for stopping additional and main goroutines.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论