1 回答
TA贡献1813条经验 获得超2个赞
好的,让我们从这个工作示例开始:
func Test_t(t *testing.T) {
// just a published, this publishes result on a chan
publish := func(s int, ch chan int, wg *sync.WaitGroup) {
ch <- s // this is blocking!!!
wg.Done()
}
wg := &sync.WaitGroup{}
wg.Add(100)
// we'll use done channel to notify the work is done
res := make(chan int)
done := make(chan struct{})
// create worker that will notify that all results were published
go func() {
wg.Wait()
done <- struct{}{}
}()
// let's create a jobs that publish on our res chan
// please note all goroutines are created immediately
for i := 0; i < 100; i++ {
go publish(i, res, wg)
}
// lets get 30 args and then wait
var resCounter int
forloop:
for {
select {
case ss := <-res:
println(ss)
resCounter += 1
// break the loop
if resCounter%30 == 0 {
// after receiving 30 results we are blocking this thread
// no more results will be taken from the channel for 5 seconds
println("received 30 results, waiting...")
time.Sleep(5 * time.Second)
}
case <-done:
// we are done here, let's break this infinite loop
break forloop
}
}
}
我希望这进一步表明它是如何完成的。
那么,您的代码有什么问题?老实说,它看起来不错(我的意思是发布了 30 个结果,然后代码等待,然后是另外 30 个结果,等等),但问题是您想在哪里等待?
我猜有几种可能:
创建工人(这就是您的代码现在的工作方式,正如我所见,它以 30 个包发布作业;请注意,您在
digit
函数中的 2 秒延迟仅适用于执行代码的 goroutine)触发工人(所以“等待”代码应该在工人函数中,不允许运行更多的工人 - 所以它必须观察发布了多少结果)
处理结果(这就是我的代码的工作方式,并且正确的同步在
forloop
)
- 1 回答
- 0 关注
- 92 浏览
添加回答
举报