假设我有一个简单的循环来执行这样的顺序测试。
for f := 1; f <= 1000; f++ {
if doTest(f) {
break
}
}
我循环遍历数字范围并对每个数字进行测试。如果一个数字的测试失败,我会中断并退出主线程。很简单。
现在,如何在四个或几个围棋例程中正确输入测试数字。基本上,我想以 4 个为一组(或任何数量的 go 例程)测试从 1 到 1000 的数字。 我是否创建 4 个从一个 channel 读取的例程并将数字按顺序输入该 channel ?还是我用一个单独的 channel 制作 4 个例程?
还有一个问题。如果其中一个未通过测试,我该如何停止所有 4 个例程?我一直在阅读 channel 上的一些文本,但我无法将它们拼凑起来。
最佳答案
您可以创建生产者/消费者系统:https://play.golang.org/p/rks0gB3aDb
func main() {
ch := make(chan int)
clients := 4
// make it buffered, so all clients can fail without hanging
notifyCh := make(chan struct{}, clients)
go produce(100, ch, notifyCh)
var wg sync.WaitGroup
wg.Add(clients)
for i := 0; i < clients; i++ {
go func() {
consumer(ch, notifyCh)
wg.Done()
}()
}
wg.Wait()
}
func consumer(in chan int, notifyCh chan struct{}) {
fmt.Printf("Start consumer\n")
for i := range in {
<-time.After(100 * time.Millisecond)
if i == 42 {
fmt.Printf("%d fails\n", i)
notifyCh <- struct{}{}
return
} else {
fmt.Printf("%d\n", i)
}
}
fmt.Printf("Consumer stopped working\n")
}
func produce(N int, out chan int, notifyCh chan struct{}) {
for i := 0; i < N; i++ {
select {
case out <- i:
case <-notifyCh:
close(out)
return
}
}
close(out)
}
生产者将 0 到 99 的数字推送到 channel ,消费者消费直到 channel 关闭。在 main 中,我们创建了 4 个客户端并将它们添加到一个 WaitGroup 中,以可靠地检查每个 goroutine 是否返回。 每个消费者都可以在 notifyCh 上发出信号,生产者停止工作并且不再生成更多数字,因此所有消费者都在当前数字之后返回。
还有一个选项可以创建 4 个 go routines,等待它们全部返回,开始接下来的 4 个 go routines。但这会增加相当大的等待开销。
既然你提到了质数,这里有一个非常酷的质数系列:https://golang.org/doc/play/sieve.go
关于go - 将顺序测试分散到 4 个 go 例程中,如果一个失败则终止所有例程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33196183/