我正在尝试剥离一组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() { var wg sync.WaitGroup for i := 0; i < 10; i++ { wg.Add(1) go doWork(wg) } wg.Wait() }
但是,当我运行此代码时,出现以下错误:
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
我很困惑,因为我写的几乎与文档示例所演示的完全一样。
您需要将指针传递给WaitGroup,而不是WaitGroup对象。当您传递实际的WaitGroup时,Go会生成该值的副本,然后调用Done()该副本。结果是原始的WaitGroup将具有10个Add,而没有Done,并且WaitGroup的每个副本将具有一个Done(),但是将WaitGroup传递给函数时,其中有许多Add。
Done()
而是传递一个指针,每个函数将引用相同的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) } }