尝试使用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中文网其他相关文章!