玩转 go,我把这段代码放在一起:
package main
import "fmt"
const N = 10
func main() {
ch := make(chan int, N)
done := make(chan bool)
for i := 0; i < N; i++ {
go (func(n int, ch chan int, done chan bool) {
for i := 0; i < N; i++ {
ch <- n*N + i
}
done <- true
})(i, ch, done)
}
numDone := 0
for numDone < N {
select {
case i := <-ch:
fmt.Println(i)
case <-done:
numDone++
}
}
for {
select {
case i := <-ch:
fmt.Println(i)
default:
return
}
}
}
基本上我有 N 个频道在做一些工作并在同一个频道上报告——我想知道所有频道什么时候完成。所以我有另一个done通道,每个工作程序 goroutine 都会在其上发送一条消息(消息无关紧要),这会导致 main 将该线程计为已完成。当计数达到 N 时,我们实际上就完成了。
这是“好”吗?有没有更惯用的方式来做到这一点?
编辑:澄清一下,我很怀疑,因为done通道似乎正在做一个通道关闭似乎是为了的工作,但当然我实际上不能在任何 goroutine 中关闭通道,因为所有的例程共享同一个通道. 所以我done用来模拟一个执行某种“缓冲关闭”的通道。
编辑2:原始代码并没有真正起作用,因为有时在done它刚刚放入的 int 之前读取来自例程的信号ch。需要一个“清理”循环。
海绵宝宝撒
相关分类