douji6667 2015-10-18 09:10
浏览 17
已采纳

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

Suppose I have a simple loop which does sequential tests like this.

 for f := 1; f <= 1000; f++ {
            if doTest(f) {
              break
            }
  }

I loop through range of numbers and do a test for each number. If test fails for one number, I break and exit the main thread. Simple enough.

Now, how do correctly feed the test numbers in say four or several go routines. Basically, I want to test the numbers from 1 to 1000 in batches of 4 (or whatever number of go routines is). Do I create 4 routines reading from one channel and feed the numbers sequentially into this channel? Or do I make 4 routines with an individual channel?

And another question. How do I stop all 4 routines if one of them fails the test? I've been reading some texts on channels but I cannot put the pieces together.

  • 写回答

2条回答 默认 最新

  • doudi5892 2015-10-18 10:24
    关注

    You can create a producer/consumer system: 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
    ")
        for i := range in {
            <-time.After(100 * time.Millisecond)
            if i == 42 {
                fmt.Printf("%d fails
    ", i)
                notifyCh <- struct{}{}
                return
            } else {
                fmt.Printf("%d
    ", i)
            }
    
        }
        fmt.Printf("Consumer stopped working
    ")
    }
    
    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)
    }
    

    The producer pushes numbers from 0 to 99 to the channel, the consumer consumes until the channel is closed. In main we create 4 clients and add them to a waitgroup to reliably check if every goroutine returned. Every consumer can signal on the notifyCh, the producer stops working and no further numbers are generated, therefor all consumers return after their current number.

    There's also an option to create 4 go routines, wait for all of them to return, start the next 4 go routines. But this adds quite an overhead on waiting.

    Since you mentioned prime numbers, here's a really cool prime seive: https://golang.org/doc/play/sieve.go

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥100 支付宝网页转账系统不识别账号
  • ¥15 基于单片机的靶位控制系统
  • ¥15 AT89C51控制8位八段数码管显示时钟。
  • ¥15 真我手机蓝牙传输进度消息被关闭了,怎么打开?(关键词-消息通知)
  • ¥15 下图接收小电路,谁知道原理
  • ¥15 装 pytorch 的时候出了好多问题,遇到这种情况怎么处理?
  • ¥20 IOS游览器某宝手机网页版自动立即购买JavaScript脚本
  • ¥15 手机接入宽带网线,如何释放宽带全部速度
  • ¥30 关于#r语言#的问题:如何对R语言中mfgarch包中构建的garch-midas模型进行样本内长期波动率预测和样本外长期波动率预测
  • ¥15 ETLCloud 处理json多层级问题