登录
首页 >  Golang >  Go问答

如何实现 sync.WaitGroup.Done() 方法的功能?

来源:stackoverflow

时间:2024-02-22 12:42:26 187浏览 收藏

哈喽!今天心血来潮给大家带来了《如何实现 sync.WaitGroup.Done() 方法的功能?》,想必大家应该对Golang都不陌生吧,那么阅读本文就都不会很困难,以下内容主要涉及到,若是你正在学习Golang,千万别错过这篇文章~希望能帮助到你!

问题内容

我为一个创建 4 个 goroutine 的程序运行了下面的代码,根据我得到的输出,我的代码似乎运行正常,但它给出了错误:- fatal 错误:所有 goroutine 都在睡觉 - 死锁!

我添加了 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:负 waitgroup counter

您将 4 添加到等待组:

wg.add(4)

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

但是您在 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

好了,本文到此结束,带大家了解了《如何实现 sync.WaitGroup.Done() 方法的功能?》,希望本文对你有所帮助!关注golang学习网公众号,给大家分享更多Golang知识!

声明:本文转载于:stackoverflow 如有侵犯,请联系study_golang@163.com删除
相关阅读
更多>
最新阅读
更多>
课程推荐
更多>