3 回答
TA贡献2036条经验 获得超8个赞
它真的不太好用。
一段时间后,由于剩余的 go-routine 等待没有 goroutine 推送的通道,会发生损耗。所以你所拥有的是一个死锁(这是一个结束程序的致命错误),而不是一个干净的结束。
总之,它“有效”是因为 go 引擎足够聪明,可以检测到死锁。
TA贡献2016条经验 获得超9个赞
一种整齐退出的方法是使用退出通道,我们通过关闭它来发出信号。(通过关闭通道发出信号很有用,因为一次可以有多个 goroutine 监听它)。
不过,还有其他方法可以做到这一点 - 如果您只有一个输出通道,那么您可以range
在它上面读取结果,close
并在完成时读取它。你可以很容易地重新编写它以这样工作。
您可以使用 async.Waitgroup
来确保 go 例程也已完成。
func main() {
// Channels for communication
fizzchan := make(chan int)
buzzchan := make(chan int)
fizzbuzzchan := make(chan int)
nonechan := make(chan int)
quit := make(chan struct{})
// Start go routine to calculate fizzbuzz challenge
go func() {
for i := 1; i <= 100; i++ {
if i%3 == 0 && i%5 == 0 {
fizzbuzzchan <- i
} else if i%3 == 0 {
fizzchan <- i
} else if i%5 == 0 {
buzzchan <- i
} else {
nonechan <- i
}
}
close(quit)
}()
// When or how does this for loop end?
OUTER:
for {
select {
case i := <-fizzchan:
fmt.Println(i, "Fizz")
case i := <-buzzchan:
fmt.Println(i, "Buzz")
case i := <-fizzbuzzchan:
fmt.Println(i, "FizzBuzz")
case i := <-nonechan:
fmt.Println(i, i)
case <-quit:
break OUTER
}
}
fmt.Println("All done")
}
- 3 回答
- 0 关注
- 155 浏览
添加回答
举报