1
我正面臨一個煩人的問題。當我嘗試使用wg.Add()
來同步我的例程時,會引發死鎖錯誤。嘗試同步goroutines時出現死鎖錯誤
package main
import (
"fmt"
"sync"
)
func hello(ch chan int, num int, wg *sync.WaitGroup) {
for {
i := <-ch
if i == num {
fmt.Println("Hello number:", i)
ch <- (num - 1)
defer wg.Done() // Same happens without defer
return
}
ch <- i
}
}
func main() {
fmt.Println("Start")
var wg sync.WaitGroup
ch := make(chan int)
for i := 0; i < 10; i++ {
wg.Add(1)
go hello(ch, i, &wg)
}
ch <- 9
wg.Wait()
fmt.Println("End")
}
輸出:
Start
Hello number: 9
Hello number: 8
Hello number: 7
Hello number: 6
Hello number: 5
Hello number: 4
Hello number: 3
Hello number: 2
Hello number: 1
Hello number: 0
fatal error: all goroutines are asleep - deadlock!
goroutine 1 [semacquire]:
sync.runtime_Semacquire(0xc04203a20c)
C:/Go/src/runtime/sema.go:47 +0x3b
sync.(*WaitGroup).Wait(0xc04203a200)
C:/Go/src/sync/waitgroup.go:131 +0x81
main.main()
C:/Users/Augusto Dias/Documents/GoLang/MT.go:34 +0x1a0
goroutine 18 [chan send]:
main.hello(0xc0420380c0, 0x0, 0xc04203a200)
C:/Users/Augusto Dias/Documents/GoLang/MT.go:13 +0x197
created by main.main
C:/Users/Augusto Dias/Documents/GoLang/MT.go:29 +0x151
exit status 2
當我使用wg.Add(9)
外塊,我沒有錯誤。
func main() {
fmt.Println("Start")
var wg sync.WaitGroup
ch := make(chan int)
wg.Add(9) // Use wg.Add(10) will raise deadlock too
for i := 0; i < 10; i++ {
go hello(ch, i, &wg)
}
ch <- 9
wg.Wait()
fmt.Println("End")
}
輸出:
Start
Hello number: 9
Hello number: 8
Hello number: 7
Hello number: 6
Hello number: 5
Hello number: 4
Hello number: 3
Hello number: 2
Hello number: 1
End
這是怎麼回事,我的意思是,爲什麼程序去睡覺時,我等着他們呢?使用相同的通道進行發送和接收可能是此問題的根源?
在您添加10到第一個WaitGroup,在你添加的第二個9.一個goroutine沒有返回。 (你也應該在函數的開始處推遲,而不是在for循環中的條件下)。 – JimB
我在第一個中得到了所有的hellos,什麼例程可以是未返回的? –
你可能會猜到它的編號爲'0',因爲你沒有看到打印的內容,堆棧跟蹤顯示它在第13行的chan發送時被阻塞。 – JimB