1 回答

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