首页 >后端开发 >Golang >如何避免'致命错误:所有 goroutine 都在睡觉 - 死锁!”与sync.WaitGroup?

如何避免'致命错误:所有 goroutine 都在睡觉 - 死锁!”与sync.WaitGroup?

Susan Sarandon
Susan Sarandon原创
2024-12-21 06:57:09383浏览

How to Avoid

理解“致命错误:所有 goroutine 都在睡觉 - 死锁!”使用sync.WaitGroup

当尝试使用sync.WaitGroup包来管理并发goroutine时,避免可怕的“致命错误:所有goroutines都在睡眠 - 死锁!”是至关重要的。此错误是由于 WaitGroup 的错误使用而引起的,特别是通过复制而不是引用传递值时。

死锁的原因

问题源于事实上,当您将实际的 WaitGroup 对象传递给 doWork 函数时,Go 会复制该值。这意味着原始 WaitGroup 会将计数器增加十次 Add() 调用,而没有任何相应的 Done() 调用。相比之下,传递给 goroutine 的 WaitGroup 的每个副本将只有一次 Done() 调用以及复制 WaitGroup 时存在的 Add() 调用的数量。

解决方案:传递指向 WaitGroup 的指针

要解决此死锁,必须将指针传递给 WaitGroup 而不是 WaitGroup 对象本身。这可以确保所有 goroutine 引用相同的 WaitGroup,并且当它们调用 Done() 时,递减计数器将应用于正确的 WaitGroup。

修改的代码

以下修改后的代码演示了指向 WaitGroup 的指针的正确用法:

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{}
    for i := 0; i < 10; i++ {
        wg.Add(1)
        go doWork(wg)
    }

    wg.Wait()
}

通过采用这种方法,您可以使用 WaitGroup 自信地管理 goroutine,避免死锁的陷阱并确保高效的并发执行。

以上是如何避免'致命错误:所有 goroutine 都在睡觉 - 死锁!”与sync.WaitGroup?的详细内容。更多信息请关注PHP中文网其他相关文章!

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