首页  >  文章  >  后端开发  >  使用 Goroutine 处理值并将结果收集到切片中时如何避免死锁?

使用 Goroutine 处理值并将结果收集到切片中时如何避免死锁?

DDD
DDD原创
2024-11-06 17:56:02969浏览

How to Avoid Deadlock When Using Goroutines to Process Values and Gather Results into a Slice?

使用 Goroutine 高效处理值并将结果收集到切片中

goroutine 的使用可以成为 Go 编程中的变革性元素,使并发任务执行和高效处理。然而,正确的实现对于避免潜在的陷阱至关重要。

问题:

当尝试在代码库中使用 goroutine 时,出现“致命错误:所有 goroutine 都处于睡眠状态 -僵局!”出现。目的是同时处理列表中的值,然后将处理结果累积到新列表中。然而,在积累阶段,困难就出现了。

代码分解:

提供的代码片段包含几个基本元素:

// Process each item with a goroutine and send output to sampleChan
go newSample(line, *replicatePtr, *timePtr, sampleChan, &wg)
  • 这个 goroutine 同时处理数据并将结果发送到名为 SampleChan 的通道。
// Read from sampleChan and put into a slice
for s := range sampleChan {
    sampleList = append(sampleList, s)
}
close(sampleChan)
  • 代码尝试从通道收集结果并将它们合并到切片中。

解决方案:

错误是由两个问题引起的:过早等待工作完成和通道关闭时机不当。以下修改解决了这些问题:

go func() {
    wg.Wait()
    close(sampleChan)
}()
  • 通过启动单独的 goroutine 将通道关闭推迟到工作人员完成后。

此外,为了风格凝聚力,请考虑重组newSample 作为结果生成的同步函数,生成以下代码:

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

这种修改后的方法提高了代码可读性,简化了测试并简化了并发管理,从而能够清晰地识别 wg.Done( ).

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

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