代码:
package main
import (
"fmt"
"time"
)
func main() {
link := make(chan bool)
stop := make(chan bool)
go a(link, stop)
go b(link)
<-stop
}
func a(link chan bool, stop chan bool) {
for i := 0; i < 20; i++ {
time.Sleep(1 * time.Second)
link <- true
}
stop <- true
}
func b(link chan bool) {
go func() {
<-link
fmt.Println("A")
}()
go func() {
<-link
fmt.Println("B")
}()
}
这段代码没有做什么特别的事情,我只是试图理解通道和goroutine,但是出了问题,goroutine在两次循环和应用程序崩溃后就休眠了。
让我们分析一下它的功能--每隔一秒,消息就会发送到link
。函数b
在两个地方接收消息,因此调用了print
A和B。因此,基本上每隔一秒,A和B就会出现在控制台中。但由于我不知道的原因,它没有出现,程序打印A和B一次,然后崩溃。我可能对这个概念理解得不够好(golang真的很不直观),所以我希望我能在这里得到一个答案。
2条答案
按热度按时间ijxebb2r1#
只有当goroutine从一个无缓冲的通道接收数据时,通道发送才会成功,在前两次发送中,有goroutine从
link
通道接收数据,但是它们只接收到一个值就终止了,并且不再有goroutine从link
接收数据,所以第三次发送link
会阻塞,因为没有其他goroutine在运行,程序就会死锁。j7dteeu82#
你的代码中的主要问题是,当你在
b
函数中通过link
通道接收到一个first消息时,你exitgoroutine,这样你就不会监听发布者,所以你需要“subscribe”这个通道,你可以通过range
来实现,比如:它将监听频道,直到您关闭它:
close(link)
,则它将退出。此外,您还可以使用
for
select
组合来执行此操作,如here所述