首页 >后端开发 >Golang >为什么使用 `sync.WaitGroup` 会导致'致命错误:所有 goroutine 都在睡眠 - 死锁!”,以及如何修复它?

为什么使用 `sync.WaitGroup` 会导致'致命错误:所有 goroutine 都在睡眠 - 死锁!”,以及如何修复它?

Mary-Kate Olsen
Mary-Kate Olsen原创
2024-12-04 20:52:13359浏览

Why Does Using `sync.WaitGroup` Lead to

使用sync.WaitGroup时理解并解决“致命错误:所有goroutines都在睡眠 - 死锁”

尝试使用sync.WaitGroup协调多个goroutines的完成时,可能会遇到错误“致命错误:所有 goroutine 都在睡觉 - 死锁!”这个神秘的消息可能会令人费解,尤其是当代码似乎是根据文档示例编写的时。

此错误的根源在于 Go 处理传递给函数的值的方式。当直接传递一个sync.WaitGroup对象时,Go会创建该值的副本,本质上是将一个不同的对象传递给每个goroutine。这会在原始 WaitGroup 和 goroutine 所操作的副本之间造成脱节。

此问题的解决方案是将指针传递给sync.WaitGroup。通过这样做,所有 goroutine 将引用相同的底层对象并一致地对其内部计数器进行操作。下面提供了使用指针的正确代码:

import "sync"

func doWork(wg *sync.WaitGroup) error {
    defer wg.Done()
    // Do some heavy lifting... request URL's or similar
    return nil
}

func main() {
    wg := &sync.WaitGroup{} // Use pointer to pass the WaitGroup
    for i := 0; i < 10; i++ {
        wg.Add(1)
        go doWork(wg)
    }
}

通过此更改,goroutine 将与 WaitGroup 对象正确交互,在开始工作之前递增其计数器,并在完成后递减计数器。因此,主函数中的 WaitGroup.Wait() 调用不会无限期地阻塞,程序将按预期执行。

以上是为什么使用 `sync.WaitGroup` 会导致'致命错误:所有 goroutine 都在睡眠 - 死锁!”,以及如何修复它?的详细内容。更多信息请关注PHP中文网其他相关文章!

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