这是我正在使用的Golang程序,目的只是为了使我的概念正确。当我运行程序时,它陷入了僵局,我不明白为什么?请任何人指出出了什么问题?
package main import ( "fmt" "sync" ) var wg sync.WaitGroup func main() { numOfGoRoutines := 10 wg.Add(numOfGoRoutines) ch := make(chan int, numOfGoRoutines) for i := 0; i < numOfGoRoutines; i++ { a := i go sqr(ch, a, wg) } wg.Wait() fmt.Println("After WAIT") close(ch) var res int for i := range ch { res += i } ch = nil fmt.Println("result = ", res) } func sqr(ch chan int, val int, wg sync.WaitGroup) { fmt.Println("go - ", val) s := val * val ch <- s wg.Done() }
输出为:
warning: GOPATH set to GOROOT (C:\\Go) has no effect go - 9 go - 0 go - 1 go - 2 go - 3 go - 4 go - 5 go - 6 go - 7 go - 8 fatal error: all goroutines are asleep - deadlock! goroutine 1 [semacquire]: sync.runtime_Semacquire(0x5bcabc) C:/Go/src/runtime/sema.go:47 +0x2d sync.(*WaitGroup).Wait(0x5bcab0) C:/Go/src/sync/waitgroup.go:127 +0xbb main.main() C:/demo/go-work/main.go:20 +0xdf exit status 2
问题是您要将传递sync.WaitGroup给goroutines 的副本,而不是引用(即指针):
sync.WaitGroup
package main import ( "fmt" "sync" ) var wg sync.WaitGroup func main() { numOfGoRoutines := 10 wg.Add(numOfGoRoutines) ch := make(chan int, numOfGoRoutines) for i := 0; i < numOfGoRoutines; i++ { a := i go sqr(ch, a, &wg) } wg.Wait() fmt.Println("After WAIT") close(ch) var res int for i := range ch { res += i } ch = nil fmt.Println("result = ", res) } func sqr(ch chan int, val int, wg *sync.WaitGroup) { fmt.Println("go - ", val) s := val * val ch <- s wg.Done() }
另外,由于wg是全局变量,您可以完全删除该参数:
wg
package main import ( "fmt" "sync" ) var wg sync.WaitGroup func main() { numOfGoRoutines := 10 wg.Add(numOfGoRoutines) ch := make(chan int, numOfGoRoutines) for i := 0; i < numOfGoRoutines; i++ { a := i go sqr(ch, a) } wg.Wait() fmt.Println("After WAIT") close(ch) var res int for i := range ch { res += i } ch = nil fmt.Println("result = ", res) } func sqr(ch chan int, val int) { fmt.Println("go - ", val) s := val * val ch <- s wg.Done() }