获取“致命错误:所有goroutines都睡着了 - 僵局!”当使用sync.WaitGroup [英] Getting "fatal error: all goroutines are asleep - deadlock!" when using sync.WaitGroup
问题描述
import我试图剥离一套goroutines,然后等待它们完成。同步
func doWork(wg sync.WaitGroup)错误{
延迟wg.Done()
//做一些繁重的工作...请求URL或类似的
返回nil
}
func main(){
var wg sync.WaitGroup $ b $ for i:= 0;我< 10; i ++ {
wg.Add(1)
go doWork(wg)
}
}
但是,当我运行这段代码时,出现以下错误:
致命错误:全部goroutines睡着了 - 僵局!
goroutine 16 [semacquire]:
sync.runtime_Semacquire(0xc20818c658)
/usr/local/Cellar/go/1.3/libexec/src/pkg/runtime/sema.goc :199 + 0x30
sync。(* WaitGroup).Wait(0xc2080544e0)
/usr/local/Cellar/go/1.3/libexec/src/pkg/sync/waitgroup.go:129+ 0x14b
main.main()
/Users/kevin/code/vrusability/scripts/oculus_share_ratings.go:150+ 0x398
我很困惑,因为我几乎写了与文档示例完全一样演示。
您需要将指针传递给WaitGroup,而不是WaitGroup对象。当您传递实际的WaitGroup时,Go将复制该值并在副本上调用 Done()
。结果是原始的WaitGroup将有10个Add和没有完成,并且WaitGroup的每个副本都有一个Done(),并且当WaitGroup传递给函数时,有很多Add都在那里。
传递指针,每个函数都会引用同一个WaitGroup。
$ p $
importsync
func doWork(wg * sync.WaitGroup)错误{
推迟wg.Done()
//做一些繁重的工作... request URL或类似的
return nil
func main(){
wg:=& sync.WaitGroup {}
for i:= 0;我< 10; i ++ {
wg.Add(1)
go doWork(wg)
}
}
I'm trying to spin off a set of goroutines, and then wait for them all to finish.
import "sync"
func doWork(wg sync.WaitGroup) error {
defer wg.Done()
// Do some heavy lifting... request URL's or similar
return nil
}
func main() {
var wg sync.WaitGroup
for i := 0; i < 10; i++ {
wg.Add(1)
go doWork(wg)
}
}
However when I run this code I get the following error:
fatal error: all goroutines are asleep - deadlock!
goroutine 16 [semacquire]:
sync.runtime_Semacquire(0xc20818c658)
/usr/local/Cellar/go/1.3/libexec/src/pkg/runtime/sema.goc:199 +0x30
sync.(*WaitGroup).Wait(0xc2080544e0)
/usr/local/Cellar/go/1.3/libexec/src/pkg/sync/waitgroup.go:129 +0x14b
main.main()
/Users/kevin/code/vrusability/scripts/oculus_share_ratings.go:150 +0x398
I'm confused because I wrote it pretty much exactly as the documentation example demonstrates.
You need to pass a pointer to the WaitGroup, and not the WaitGroup object. When you pass the actual WaitGroup, Go makes a copy of the value, and calls Done()
on the copy. The result is the original WaitGroup will have ten Add's and no Done's, and each copy of the WaitGroup will have one Done() and however many Add's were there when the WaitGroup was passed to the function.
Pass a pointer instead, and every function will reference the same 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)
}
}
这篇关于获取“致命错误:所有goroutines都睡着了 - 僵局!”当使用sync.WaitGroup的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!