去等goroutines,但同时做的东西

时间:2016-10-06 10:20:46

标签: go concurrency goroutine

我有以下go-Code:

int loss_weight_size() const;  // Returns the number of elements currently in the field
void add_foo(int32 value); // Appends a new element to the field with the given value.

对于行func execTask(input int, results chan<- int) { //do stuff (in my case, start process and return something) results <- someResult } func main() { results := make(chan int) for _, task := range tasks { go execTask(task, results) } for result := range results { fmt.Println(result) } } ,我收到错误消息: for result := range results {。在例程fatal error: all goroutines are asleep - deadlock!中,我实际上使用os / exec执行一个进程,所以我不知道execTask中有多少结果。所以我必须等待所有进程的完成,但同时对结果做一些事情。当所有进程终止时,我的go-Programm也可能被终止。

我该怎么做?

谢谢, 拉斯

1 个答案:

答案 0 :(得分:5)

您收到死锁错误,因为您没有关闭results频道。因此,即使在所有main完成后,results仍在等待execTask上的更多数据,并且没有其他内容写入results

您可以使用sync.WaitGroup

解决此问题
func main() {
    var wg sync.WaitGroup
    results := make(chan int)

    wg.Add(len(tasks))
    for _, task := range tasks {
        go func(task int) {
            defer wg.Done()
            execTask(task, results)
        }(task)
    }

    go func() {
        wg.Wait() // wait for each execTask to return
        close(results) // then close the results channel
    }

    for result := range results {
        fmt.Println(result)
    }
}

至于处理execTask结果而其他进程仍在执行时,您已经有了正确的想法。只需在results范围循环中处理它们。如果你想要更多的并发执行,可以在那里启动一些goroutine。