2016-10-06 20 views
2

我有以下中间人代码:去等待够程,但做的东西在此期间

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!。在例程execTask中,我实际上使用os/exec来执行一个进程,所以我不知道results中有多少结果。所以我必须等待所有流程的完成,但同时要对结果进行一些处理。当所有进程终止时,我的程序也可能被终止。

我该怎么做?

感谢, 拉尔斯

+0

结果:=令(CHAN INT) 为_,任务:=一系列任务{ 去execTask(任务,结果) } 任务还呼吁的结果,可能会导致僵局.. – MarmiK

回答

5

你所得到的死锁错误,因为你不关闭results通道。因此,即使所有execTask已完成,main仍在等待更多的数据results,并且没有任何其他信息写入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。

+3

不要使用你的封闭范围内的''任务'就像那样。使你的关闭接受'任务int'并将其传入:请参阅https://github.com/golang/go/wiki/CommonMistakes#using-goroutines-on-loop-iterator-variables – jcbwlkr

+0

fixed .. thanks .. – abhink