2016-10-06 40 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