考虑这个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
我正在尝试模拟从一个线程到另外两个线程的通信,但看起来上面的代码在我的本地运行正常而不是在操场上。
有没有让这个程序有效的技巧?
答案 0 :(得分:2)
您应该从default
语句中删除select
子句。
由于select
语句在for
循环内且default
子句阻止它阻塞,因此循环必须经过很多循环才能收到任何消息。
看起来Playground会检测到它并停止程序。
答案 1 :(得分:1)
正如@ dev.bmax已提到的那样,您以错误的方式使用default
。
使用default
关键字检查这个小article。
另外,尝试在程序开头添加runtime.GOMAXPROCS(4)
,运行几次并检查输出以查看它是如何工作的:
https://play.golang.org/p/TLDHNg6urB
以下是您的正确示例:
https://play.golang.org/p/bc0TGdmx1Y
请注意,在这种情况下,您应该使用不同的通道来停止其他和主要的goroutines。