我正在尝试遵循http://blog.golang.org/pipelines/bounded.go上发布的有界 goroutine 示例。我遇到的问题是,如果有更多的工作人员投入工作,那么工作量就会增加,额外的工作人员永远不会被取消。其他一切似乎都有效,值被计算并记录下来,但是当我关闭groups通道时,工作人员只是挂在 range 语句上。
我想我不明白(在我的代码和示例代码中)是工人如何知道何时没有更多工作要做以及他们应该退出?
更新
一个工作(即非工作)示例发布在http://play.golang.org/p/T7zBCYLECp。它显示了工人的僵局,因为他们都睡着了,没有工作要做。我感到困惑的是,我认为示例代码也会有同样的问题。
这是我目前使用的代码:
// Creates a pool of workers to do a bunch of computations
func 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
}
这是用数据填充通道的代码:
// Retrieves the groups of data the must be computed
func 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
}
这是读取通道以进行计算的代码。
// Computes the results for the groups of data
func 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
}
}
}
MM们
繁星coding
相关分类