首页  >  文章  >  后端开发  >  为什么在外部函数中使用 Sync.WaitGroup 的副本会导致 goroutine 中输出丢失?

为什么在外部函数中使用 Sync.WaitGroup 的副本会导致 goroutine 中输出丢失?

Mary-Kate Olsen
Mary-Kate Olsen原创
2024-11-06 14:00:03492浏览

Why does using a copy of Sync.WaitGroup in an external function lead to missing output in a goroutine?

将 Sync.WaitGroup 与外部函数结合使用

在提供的代码中,目的是让主 goroutine 通过使用通道和通道来打印从 1 到 11 的数字。等组。但是,它偶尔会跳过数字 11,导致输出不完整。

问题是由于将sync.WaitGroup 错误地传递给外部函数Print 引起的。通过将 WaitGroup 的副本传递给函数,它无法对主 goroutine 正在等待的原始等待组执行必要的 Done() 调用。

最佳解决方案:

推荐的解决方案包括修改代码如下:

<code class="go">func main() {
    ch := make(chan int)

    var wg sync.WaitGroup
    wg.Add(2)

    go Print(ch, &wg)

    go func() {
        for i := 1; i <= 11; i++ {
            ch <- i
        }
        close(ch)
        defer wg.Done()
    }()

    wg.Wait()
}

func Print(ch <-chan int, wg *sync.WaitGroup) {
    for n := range ch { // reads from channel until it's closed
        fmt.Println(n)
    }
    defer wg.Done()
}</code>

在此修复中,Print 函数接收指向等待组的指针,确保在

替代解决方案:

或者,可以通过直接关闭通道来消除 Print 函数中对 WaitGroup 的需要发送完所有数字后:

<code class="go">func Print(ch <-chan int) {
    for n := range ch { // reads from channel until it's closed
        fmt.Println(n)
    }
}</code>

在这种情况下,主 Goroutine 必须等待通道关闭:

<code class="go">wg.Wait()
close(ch)</code>

以上是为什么在外部函数中使用 Sync.WaitGroup 的副本会导致 goroutine 中输出丢失?的详细内容。更多信息请关注PHP中文网其他相关文章!

声明:
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn