且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

去程序越来越僵局

更新时间:2022-10-14 23:13:34

问题是,您正在将 sync.WaitGroup 的副本传递给goroutines,而不是引用(即指针):

 包主
$ b导入(
fmt
同步


var wg sync.WaitGroup

func main(){

numOfGoRoutines:= 10
wg.Add(numOfGoRoutines)
ch:= make(chan int,numOfGoRoutines)

for i:= 0;我< numOfGoRoutines; i ++ {
a:= i
转到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 wg.Done()
}

此外,由于 wg 是一个全局变量,因此您可以删除参数完全:

  package main 

import(
fmt
同步


var wg sync.WaitGroup

func main(){

numOfGo例程:= 10
wg .Add(numOfGoRoutines)
ch:= make(chan int,numOfGoRoutines)

for i:= 0;我< numOfGoRoutines; i ++ {
a:= i
转到sqr(ch,a)
}
wg.Wait()
fmt.Println(After WAIT)
关闭(ch)
var res int
为i:=范围ch {
res + = i
}
ch = nil
fmt.Println (result =,res)

}

func sqr(ch chan int,val int){
fmt.Println(go - ,val )
s:= val * val
ch wg.Done()
}


Here is my Golang program which I am playing with just to get my concepts right. When I run the program it is deadlocked I don't understand why ? Please anyone point out what is going wrong ?

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()
}

and the output is:

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

The problem is that you're passing a copy of sync.WaitGroup to the goroutines, rather than a reference (i.e. a pointer):

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()
}

Additionally, since wg is a global variable, you could just remove the parameter entirely:

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()
}