go - 将顺序测试分散到 4 个 go 例程中,如果一个失败则终止所有例程

标签 go

假设我有一个简单的循环来执行这样的顺序测试。

 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/

相关文章:

go - revel 框架中的缓存失效

go - 制作使用nmap的多个goroutine

html - 使用 Go 提供 HTML 页面

go - 将 RSA PrivateKey PEM 写入 golang 文件

戈兰 : panic after mutex locks have been held for too long

走吧,路很崎岖。感谢帮助

go - 如何解决与现有 child 的问题冲突?

go - 消除类型转换中的重复代码

go - 交换两个数字 golang

go - 具有多个用户的服务器实例