首页 > 解决方案 > sync.WaitGroup.Done() 如何实际工作?

问题描述

我为创建 4 个 goroutine 的程序运行了以下代码,根据我得到的输出,我的代码似乎运行正常,但它给出了错误:-fatal error: all goroutines are asleep - deadlock!

我添加了 4 个 WaitGroups,并且随着每个 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

标签: gogoroutine

解决方案


实际上我没有遇到死锁,而是另一个错误:panic: sync: negative WaitGroup counter.

您将 4 添加到等待组:

wg.Add(4)

然后你wg.Done()sort()4 个启动的 goroutine 中调用。没关系。

但你也有一个“最终”的sort()电话main

sort(final)

而 insidewg.Done()也会被调用:

panic: sync: negative WaitGroup counter

一个“简单”的解决方法是在调用之前将一个添加到等待组sort

wg.Add(1)
sort(final)

推荐阅读