【问题标题】:Go wait for goroutines but do stuff in the meantime去等待 goroutines 但同时做一些事情
【发布时间】:2016-10-06 10:20:46
【问题描述】:

我有以下 go-Code:

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中有多少结果。所以我必须等待我所有的过程完成,但同时对结果做一些事情。当所有进程都终止时,我的 go-Programm 也可能会终止。

我该怎么做?

谢谢, 拉尔斯

【问题讨论】:

  • results := make(chan int) for _, task := range tasks { go execTask(task, results) } 任务也在调用结果,这会导致死锁..

标签: go concurrency goroutine


【解决方案1】:

您遇到死锁错误是因为您没有关闭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。

【讨论】:

猜你喜欢
  • 2020-02-02
  • 2014-10-17
  • 2011-10-09
  • 2021-09-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-11-30
相关资源
最近更新 更多