Go程序陷入僵局
Go program getting deadlock
这是我正在玩的 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
的副本传递给 goroutine,而不是引用(即指针):
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
是一个全局变量,您可以完全删除该参数:
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()
}
这是我正在玩的 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
的副本传递给 goroutine,而不是引用(即指针):
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
是一个全局变量,您可以完全删除该参数:
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()
}