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 關注
- 136 瀏覽
添加回答
舉報
