package main

import (
    "fmt"
    "runtime"
    "sync"
    "time"
)

func main() {
    intInputChan := make(chan int, 50)
    var wg sync.WaitGroup
    for i := 0; i < 3; i++ {
        wg.Add(1)
        go worker(intInputChan, wg)
    }
    for i := 1; i < 51; i++ {
        fmt.Printf("Inputs. %d \n", i)
        intInputChan <- i
    }
    close(intInputChan)
    wg.Wait()
    fmt.Println("Existing Main App... ")
    panic("---------------")
}

func worker(input chan int, wg sync.WaitGroup) {
    defer func() {
        fmt.Println("Executing defer..")
        wg.Done()
    }()

    for {
        select {
        case intVal, ok := <-input:
            time.Sleep(100 * time.Millisecond)
            if !ok {
                input = nil
                return
            }
            fmt.Printf("%d  %v\n", intVal, ok)

        default:
            runtime.Gosched()
        }
    }

}

抛出的错误是。

致命错误:所有 goroutine 都处于 sleep 状态 - 死锁!

goroutine 1 [semacquire]:
同步。(*WaitGroup)。等待(0xc082004600)
c:/go/src/sync/waitgroup.go:132 +0x170
main.main()
E:/Go/go_projects/go/src/Test.go:22 +0x21a

最佳答案

我刚刚尝试过( playground )传递 wg *sync.WaitGroup 并且它有效。

传递 sync.WaitGroup 意味着传递 sync.WaitGroup 的副本(按值传递):goroutine 将 Done() 提到不同的 sync.WaitGroup

var wg sync.WaitGroup
for i := 0; i < 3; i++ {
    wg.Add(1)
    go worker(intInputChan, &wg)
}

请注意 &wg :您通过值传递指向原始 sync.WaitGroup 的指针,供 goroutine 使用。

关于go - 为什么所有的 goroutine 都睡着了——死锁。识别瓶颈,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/28691035/

10-10 12:33