sync.WaitGroup.Done() 是如何工作的?
How does sync.WaitGroup.Done() actually work?
我 运行 下面的代码用于创建 4 个 goroutines 的程序,根据我得到的输出,我的代码 运行 似乎正确但它给出了错误:- fatal error: all goroutines are asleep - deadlock!
我添加了 4 个 WaitGroup,当每个 goroutine 完成时,我做了 wg.Done(),但我仍然不明白为什么会发生这样的错误。
我的代码:
package main
import (
"fmt"
"sync"
)
var wg sync.WaitGroup
func sort(x []int) {
fmt.Println("Initial: ", x)
var i int
var j int
for i = 0; i < len(x); i++ {
for j = 0; j < len(x)-i-1; j++ {
if x[j] > x[j+1] {
temp := x[j+1]
x[j+1] = x[j]
x[j] = temp
}
}
}
fmt.Println("Sorted: ", x)
wg.Done()
}
func main() {
fmt.Println("Enter an array of number preferrably in multiples of 4:- ")
inputSlice := make([]int, 0, 1)
for true {
var n int
fmt.Print("Enter the number: ")
fmt.Scan(&n)
inputSlice = append(inputSlice, n)
fmt.Print("Do you want to continue adding numbers (y/n) ? ")
var char string
fmt.Scan(&char)
if char == "n" || char == "N" {
if len(inputSlice)%4 == 0 {
break
} else {
fmt.Println("Please enter more ", 4-len(inputSlice)%4, " numbers")
}
}
fmt.Println("Test: ", n)
fmt.Println("Input: ", char)
}
fmt.Println("Initial: ", inputSlice)
size := len(inputSlice)
wg.Add(4)
div := (size / 4)
sort1 := inputSlice[:div]
go sort(sort1)
sort2 := inputSlice[div:(div * 2)]
go sort(sort2)
sort3 := inputSlice[(div * 2):(div * 3)]
go sort(sort3)
sort4 := inputSlice[(div * 3):]
go sort(sort4)
wg.Wait()
final := make([]int, 0, 1)
for _, val := range sort1 {
final = append(final, val)
}
for _, val := range sort2 {
final = append(final, val)
}
for _, val := range sort3 {
final = append(final, val)
}
for _, val := range sort4 {
final = append(final, val)
}
sort(final)
fmt.Println("Sorted: ", final)
}
我的输出:
Enter an array of number preferrably in multiples of 4:-
Enter the number: 1
Do you want to continue adding numbers (y/n) ? y
Test: 1
Input: y
Enter the number: 2
Do you want to continue adding numbers (y/n) ? y
Test: 2
Input: y
Enter the number: 3
Do you want to continue adding numbers (y/n) ? y
Test: 3
Input: y
Enter the number: 4
Do you want to continue adding numbers (y/n) ? n
Initial: [1 2 3 4]
fatal error: all goroutines are asleep - deadlock!
goroutine 1 [chan send]:
main.main()
C:/Deepan/Text Books/NITK - Coursera/GoLang/Course3/week3.go:61 +0x658
exit status 2
实际上我遇到的不是死锁而是另一个错误:panic: sync: negative WaitGroup counter
.
您将 4 添加到等待组:
wg.Add(4)
然后你在 sort()
中调用 wg.Done()
,在 4 个已启动的 goroutine 中。没关系。
但是您在 main
中还有一个“最终”sort()
调用:
sort(final)
并且在wg.Done()
里面也会被调用:
panic: sync: negative WaitGroup counter
一种“简单”的解决方法是在调用 sort
之前向等待组添加一个:
wg.Add(1)
sort(final)
总共 5 次 sort() 调用,意味着 5 wg.Done(),但是您添加了 wg.Add(4) 而已。这导致
panic: sync: negative WaitGroup counter
我 运行 下面的代码用于创建 4 个 goroutines 的程序,根据我得到的输出,我的代码 运行 似乎正确但它给出了错误:- fatal error: all goroutines are asleep - deadlock!
我添加了 4 个 WaitGroup,当每个 goroutine 完成时,我做了 wg.Done(),但我仍然不明白为什么会发生这样的错误。
我的代码:
package main
import (
"fmt"
"sync"
)
var wg sync.WaitGroup
func sort(x []int) {
fmt.Println("Initial: ", x)
var i int
var j int
for i = 0; i < len(x); i++ {
for j = 0; j < len(x)-i-1; j++ {
if x[j] > x[j+1] {
temp := x[j+1]
x[j+1] = x[j]
x[j] = temp
}
}
}
fmt.Println("Sorted: ", x)
wg.Done()
}
func main() {
fmt.Println("Enter an array of number preferrably in multiples of 4:- ")
inputSlice := make([]int, 0, 1)
for true {
var n int
fmt.Print("Enter the number: ")
fmt.Scan(&n)
inputSlice = append(inputSlice, n)
fmt.Print("Do you want to continue adding numbers (y/n) ? ")
var char string
fmt.Scan(&char)
if char == "n" || char == "N" {
if len(inputSlice)%4 == 0 {
break
} else {
fmt.Println("Please enter more ", 4-len(inputSlice)%4, " numbers")
}
}
fmt.Println("Test: ", n)
fmt.Println("Input: ", char)
}
fmt.Println("Initial: ", inputSlice)
size := len(inputSlice)
wg.Add(4)
div := (size / 4)
sort1 := inputSlice[:div]
go sort(sort1)
sort2 := inputSlice[div:(div * 2)]
go sort(sort2)
sort3 := inputSlice[(div * 2):(div * 3)]
go sort(sort3)
sort4 := inputSlice[(div * 3):]
go sort(sort4)
wg.Wait()
final := make([]int, 0, 1)
for _, val := range sort1 {
final = append(final, val)
}
for _, val := range sort2 {
final = append(final, val)
}
for _, val := range sort3 {
final = append(final, val)
}
for _, val := range sort4 {
final = append(final, val)
}
sort(final)
fmt.Println("Sorted: ", final)
}
我的输出:
Enter an array of number preferrably in multiples of 4:-
Enter the number: 1
Do you want to continue adding numbers (y/n) ? y
Test: 1
Input: y
Enter the number: 2
Do you want to continue adding numbers (y/n) ? y
Test: 2
Input: y
Enter the number: 3
Do you want to continue adding numbers (y/n) ? y
Test: 3
Input: y
Enter the number: 4
Do you want to continue adding numbers (y/n) ? n
Initial: [1 2 3 4]
fatal error: all goroutines are asleep - deadlock!
goroutine 1 [chan send]:
main.main()
C:/Deepan/Text Books/NITK - Coursera/GoLang/Course3/week3.go:61 +0x658
exit status 2
实际上我遇到的不是死锁而是另一个错误:panic: sync: negative WaitGroup counter
.
您将 4 添加到等待组:
wg.Add(4)
然后你在 sort()
中调用 wg.Done()
,在 4 个已启动的 goroutine 中。没关系。
但是您在 main
中还有一个“最终”sort()
调用:
sort(final)
并且在wg.Done()
里面也会被调用:
panic: sync: negative WaitGroup counter
一种“简单”的解决方法是在调用 sort
之前向等待组添加一个:
wg.Add(1)
sort(final)
总共 5 次 sort() 调用,意味着 5 wg.Done(),但是您添加了 wg.Add(4) 而已。这导致
panic: sync: negative WaitGroup counter