Go程序陷入僵局

标签 go goroutine

这是我正在使用的 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()
}

关于Go程序陷入僵局,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38211875/

相关文章:

google-app-engine - 通过将 key 存储到 session golang 中来更快地加载页面

go - Golang 的 Revel 是否可以部署为二进制?

dictionary - 存储具有重复键的键值对的数据结构

google-app-engine - App Engine 转到 : How to kill a running goroutine

go - 在golang中 sleep 会阻止其他goroutine吗?

json - 如何将字符串(映射数组)转换为 GOLANG 中的结构?

go - 运行时访问 Go 中的符号

go - 我怎样才能生成依赖于它们的前辈的例程?

go - 所有 go routines 都睡着了 - 死锁

concurrency - 等待 n 个 goroutine 终止