go - 等待 sync.Waitgroup 延迟

标签 go

当从下面的 goroutine 在 channel 上发送时,我有以下代码进入死锁:

package main

import (
    "fmt"
    "sync"
)

func main() {
    for a := range getCh(10) {
        fmt.Println("Got:", a)
    }
}

func getCh(n int) <-chan int {
    var wg sync.WaitGroup
    ch := make(chan int)
    defer func() {
        fmt.Println("closing")
        wg.Wait()
        close(ch)
    }()
    wg.Add(1)
    go func() {
        defer wg.Done()
        for i := 0; i < n; i++ {
            ch <- i
        }
    }()
    wg.Add(1)
    go func() {
        defer wg.Done()
        for i := n; i < 0; i-- {
            ch <- i
        }
    }()

    return ch
}

我知道在defer中使用wg.Wait()是合法的。但是我一直没能在以 channel 作为返回值的函数中找到用途。

最佳答案

我认为您犯的错误是您认为 deferred 函数也将异步运行。但事实并非如此,因此 getCh() 将阻塞在其延迟部分,等待 WaitGroup。但是由于没有人从 channel 中读取,写入 channel 的 goroutines 无法返回,因此 WaitGroup 导致死锁。尝试这样的事情:

func getCh(n int) <-chan int {
    ch := make(chan int)
    go func() {
        var wg sync.WaitGroup
        wg.Add(1)
        go func(n int) {
            defer wg.Done()
            for i := 0; i < n; i++ {
                ch <- i
            }
        }(n)
        wg.Add(1)
        go func(n int) {
            defer wg.Done()
            for i := n; i > 0; i-- {
                ch <- i
            }
        }(n)
        wg.Wait()
        fmt.Println("closing")
        close(ch)
    }()

    return ch
}

关于go - 等待 sync.Waitgroup 延迟,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37943036/

相关文章:

http - 为什么 "http.Get()"方法在 go 中抛出致命异常?

golang diff类型的函数提供 "unresolved type”

firebase - 如何验证JWT?

go - Visual Studio代码:转到-重新格式化后,选项卡设置无效

google-app-engine - 如何将 *.appspot.com 重定向到自定义域

go - 在 golang 中初始化 C 结构时,结构初始化程序中的值太少

json - 在 go 中进行 json 序列化后的 Anonymus 结构

失败 - 预期 'package' ,发现 'EOF'

go - 如何访问包外的模板?

go - 使用 golang 在谷歌日历上添加提醒