all goroutines are asleep - deadlock
簡單使用:
package main import ( "sync" ) type httpPkg struct{} func (httpPkg) Get(url string) {} var http httpPkg func main() { var wg sync.WaitGroup var urls = []string{ "http://www.golang.org/", "http://www.google.com/", "http://www.somestupidname.com/", } for _, url := range urls { // Increment the WaitGroup counter. wg.Add(1) // Launch a goroutine to fetch the URL. go func(url string) { // Decrement the counter when the goroutine completes. defer wg.Done() // Fetch the URL. http.Get(url) }(url) } // Wait for all HTTP fetches to complete. wg.Wait() }
跟java的CountdownLatch
差不多,也是阻塞等待所有任務完成之后再繼續執行。
簡單使用就是在創建一個任務的時候wg.Add(1)
, 任務完成的時候使用wg.Done()
來將任務減一。使用wg.Wait()
來阻塞等待所有任務完成。
然后我就寫了一個例子:
func main() {
var wg sync.WaitGroup
ch := make(chan int, 1000)
for i := 0; i < 1000; i++ {
wg.Add(1)
go doSomething(i, wg, ch)
}
wg.Wait()
fmt.Println("all done")
for i := 0; i < 1000; i++ {
dd := <-ch
fmt.Println("from ch:"+strconv.Itoa(dd))
}
}
func doSomething(index int, wg sync.WaitGroup, ch chan int) {
defer wg.Done()
fmt.Println("start done:" + strconv.Itoa(index))
//time.Sleep(20 * time.Millisecond)
ch <- index
}
然后就報錯了:
fatal error: all goroutines are asleep - deadlock!
goroutine 1 [semacquire]:
sync.runtime_Semacquire(0xc42001608c)
/usr/local/Cellar/go/1.10.3/libexec/src/runtime/sema.go:56 +0x39
sync.(*WaitGroup).Wait(0xc420016080)
/usr/local/Cellar/go/1.10.3/libexec/src/sync/waitgroup.go:129 +0x72
main.main()
/Users/taoli/go/src/github.com/c60/cai/tx_gorutine.go:16 +0xea
怎么回事,他說死鎖了。
原來這是說,所有的協程都運行完了,你這邊還在等待。
什么原因導致的呢?
原來是golang里如果方法傳遞的不是地址,那么就會做一個拷貝,所以這里調用的wg根本就不是一個對象。
傳遞的地方傳遞地址就可以了:
go doSomething(i, &wg, ch) func doSomething(index int, wg *sync.WaitGroup, ch chan int) {
作者:ironman_
鏈接:https://www.jianshu.com/p/4c2c80076094
來源:簡書
著作權歸作者所有。商業轉載請聯系作者獲得授權,非商業轉載請注明出處。