我正在嘗試遵循h(huán)ttp://blog.golang.org/pipelines/bounded.go上發(fā)布的有界 goroutine 示例。我遇到的問題是,如果有更多的工作人員投入工作,那么工作量就會增加,額外的工作人員永遠(yuǎn)不會被取消。其他一切似乎都有效,值被計算并記錄下來,但是當(dāng)我關(guān)閉groups通道時,工作人員只是掛在 range 語句上。我想我不明白(在我的代碼和示例代碼中)是工人如何知道何時沒有更多工作要做以及他們應(yīng)該退出?更新一個工作(即非工作)示例發(fā)布在http://play.golang.org/p/T7zBCYLECp。它顯示了工人的僵局,因為他們都睡著了,沒有工作要做。我感到困惑的是,我認(rèn)為示例代碼也會有同樣的問題。這是我目前使用的代碼:// Creates a pool of workers to do a bunch of computationsfunc computeAll() error { done := make(chan struct{}) defer close(done) groups, errc := findGroups(done) // start a fixed number of goroutines to schedule with const numComputers = 20 c := make(chan result) var wg sync.WaitGroup wg.Add(numComputers) for i := 0; i < numComputers; i++ { go func() { compute(done, groups, c) wg.Done() }() } go func() { wg.Wait() close(c) }() // log the results of the computation for r := range c { // log the results } if err := <-errc; err != nil { return err } return nil}這是用數(shù)據(jù)填充通道的代碼:// Retrieves the groups of data the must be computedfunc findGroups(done <-chan struct{}) (<-chan model, <-chan error) { groups := make(chan model) errc := make(chan error, 1) go func() { // close the groups channel after find returns defer close(groups) group, err := //... code to get the group ... if err == nil { // add the group to the channel select { case groups <- group: } } }() return groups, errc}這是讀取通道以進(jìn)行計算的代碼。// Computes the results for the groups of datafunc compute(done <-chan struct{}, groups <-chan model, c chan<- result) { for group := range groups { value := compute(group) select { case c <- result{value}: case <-done: return } }}
2 回答

MM們
TA貢獻(xiàn)1886條經(jīng)驗 獲得超2個贊
因為您正在嘗試讀取errc并且它是空的,除非出現(xiàn)錯誤。
//編輯
computeAll()<- errc如果沒有錯誤,將始終阻止,另一種方法是使用類似的方法:
func computeAll() (err error) {
.........
select {
case err = <-errc:
default: //don't block
}
return
}

繁星coding
TA貢獻(xiàn)1797條經(jīng)驗 獲得超4個贊
嘗試像 OneOfOne 所說的那樣關(guān)閉錯誤
go func() {
wg.Wait()
close(c)
close(errc)
}()
// log the results of the computation
for r := range c { // log the results }
if err := range errc {
if err != nil {
return err
}
}
- 2 回答
- 0 關(guān)注
- 221 瀏覽
添加回答
舉報
0/150
提交
取消