首页  >  文章  >  后端开发  >  使用 Goroutines 进行并行处理和结果收集时如何避免死锁?

使用 Goroutines 进行并行处理和结果收集时如何避免死锁?

Barbara Streisand
Barbara Streisand原创
2024-11-07 02:09:03484浏览

How to Avoid Deadlocks When Using Goroutines for Parallel Processing and Result Gathering?

了解并行处理和结果收集的 Goroutine

背景

你的目标是利用 Go 中的 Goroutines 并行处理项目,收集它们的结果切成片。然而,您遇到了一个令人困惑的死锁错误:“all goroutine are sleep - deadlock!”

解决方案

该错误源于代码中的两个问题:

  1. 延迟收集: 在收集结果之前你正在等待所有 goroutine 完成,这是不正确的。
  2. 通道过早关闭: 结果收集后通道关闭循环结束,提前终止迭代。

修订代码

要纠正这些问题,引入一个 goroutine,在工作线程完成时异步关闭通道:

for i, line := range contents {
  wg.Add(1)
  go newSample(line, *replicatePtr, *timePtr, sampleChan, &wg)
}

go func() {
  wg.Wait()
  close(sampleChan)
}()

for s := range sampleChan {
  ..
}

说明

  • 异步通道关闭:匿名goroutine在所有worker完成后关闭通道,避免循环提前终止。
  • 风格推荐:考虑使用不采用通道和等待组的同步辅助函数 (newSample),简化代码并增强可测试性。

重构以提高效率

如果您需要固定数量的工作人员以获得最佳效率,请按如下方式重构代码:

for i, line := range contents {
  wg.Add(1)
  go func(line string) {
    defer wg.Done()
    sampleChan <- newSample(line, *replicatePtr, *timePtr)
  }(line)
}

这将并发原语保持在一起并简化了各种并发模式的重构。

以上是使用 Goroutines 进行并行处理和结果收集时如何避免死锁?的详细内容。更多信息请关注PHP中文网其他相关文章!

声明:
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn