我有以下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也可能被终止。
我该怎么做?
谢谢, 拉斯
答案 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。