首页 >后端开发 >Golang >从 Go 中的 Goroutine 收集结果时如何避免死锁?

从 Go 中的 Goroutine 收集结果时如何避免死锁?

Mary-Kate Olsen
Mary-Kate Olsen原创
2024-11-07 12:56:03765浏览

How to Avoid Deadlocks When Gathering Results from Goroutines in Go?

使用 Goroutines 处理值并将结果收集到切片中

Goroutines 是 Go 中并发编程的基本概念。它们允许您同时执行多个任务,而不会阻塞主线程。然而,使用 goroutine 可能会很棘手,尤其是在从多个 goroutine 收集结果时。

问题陈述

一位开发人员尝试使用 goroutine 来处理一系列items 并将处理后的值收集到切片中。然而,他们遇到了可怕的“所有 goroutine 都在睡觉——死锁!”错误。

死锁的根本原因

发生死锁是因为代码在尝试收集结果之前等待所有 goroutine 完成处理。这就造成了这样一种情况:goroutine 正在等待切片可供写入,而主线程正在等待 goroutine 完成处理。

解决方案

为了解决死锁,需要引入异步关闭用于goroutine和主线程之间通信的通道。下面修改后的代码显示了解决方案:

// ...

// Create a channel to receive the processed values
sampleChan := make(chan sample)

var wg sync.WaitGroup

// Process each item in the list with a goroutine
for i, line := range contents {
    wg.Add(1)
    go func(line string) {
        defer wg.Done()
        // Process the item and send the result on the channel
        sampleChan <- newSample(line, *replicatePtr, *timePtr)
    }(line)
}

// Asyncronously close the channel when all goroutines are done
go func() {
    wg.Wait()
    close(sampleChan)
}()

// Read from the channel and gather results into a slice
var sampleList []sample
for s := range sampleChan {
    sampleList = append(sampleList, s)
}

// ...

通过异步关闭通道,即使 goroutine 仍在处理,主线程也可以继续收集结果。这打破了死锁,让代码能够正确执行。

其他注意事项

值得注意的是,虽然这个解决方案解决了死锁,但它并不是一个完整的解决方案用于管理此特定场景中的并发性。根据需求和 goroutine 的数量,可能需要额外的同步和错误处理机制来确保代码的可靠性和正确性。

以上是从 Go 中的 Goroutine 收集结果时如何避免死锁?的详细内容。更多信息请关注PHP中文网其他相关文章!

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