1 回答

TA貢獻1820條經驗 獲得超9個贊
barrier
您正在使用的軟件包已被棄用,取而代之的是 Go 包含的context
軟件包。你應該改用context
。(broadcast
目前,您使用的軟件包也沒有真正給您帶來任何好處。)
不過,眼前的問題似乎非常明顯:運行的(單個)goroutineworkerOne
從通道讀取,并且只有當通道關閉(因此ok
變為false
)時,它才會調用bar.Fall()
刪除屏障。同時,(單個)goroutine 運行匿名發送者函數:
go func() {
? ? for i := 0; i < 5; i++ {
? ? ? ? d.x = i
? ? ? ? log.Printf("Sending %v", d)
? ? ? ? b.Submit(d)
? ? }
? ? <-bar.Barrier()
? ? b.Close()
}()
通過包的(非常)簡單的消息發布/訂閱接口提交五個項目broadcast,然后等待屏障下降。唯一能夠放下障礙的 Goroutine(把它想象成唯一能在這里拯救你的地鼠workerOne)就是正在運行的 goroutine 。他現在正在頻道接收中等待:
? ? v, ok := <-ch
您在主 Goroutine 中正在通過sync.WaitGroup變量等待:
w.Wait()
運行匿名發送函數的地鼠正在等待:
? ? <-bar.Barrier()
誰——在不同的 Go 例程中運行或等待的三個地鼠中的哪一個——將向匿名發送者中的地鼠發出信號,應該v, ok := <-ch得到!ok結果?唯一能做到的就是地鼠奔跑workerOne,但他被困住了。
該broadcast軟件包永遠不會為您關閉您的頻道。取消注冊頻道只是將其從廣播公司的輸出頻道中刪除,從而使未注冊的頻道保持開放狀態;完全有效地關閉廣播公司只會注銷所有頻道,再次讓它們保持開放狀態。因此,如果您希望關閉自己的頻道,則必須自己在其他地方執行此操作。
或者,您可以修改您的設置workerOne,使其不依賴于關閉的通道。例如,您的變量d有 anx int和 a y string; 您可以選擇其中一個或兩個,并確定讀取“drop thebarrier”的字符串值(可能int還具有某些特定值)意味著“bar.Fall()立即調用”。如果您這樣做,您從這兩個非標準包中獲得的收益會更少。
- 1 回答
- 0 關注
- 183 瀏覽
添加回答
舉報