【问题标题】:Golang: can WaitGroup leak with go-routinesGolang:WaitGroup 是否可以通过 go-routines 泄漏
【发布时间】:2017-08-21 18:17:22
【问题描述】:

我计划实现一个 go-routine 并有一个 sync.WaitGroup 来同步创建的 go-routine 的结束。我基本上使用go <function> 创建了一个线程。所以它是这样的:

main() {
    var wg sync.WaitGroup
    for <some condition> {
        go myThread(wg)
        wg.Add(1)
    }
    wg.wait()
}

myThread(wg sync.WaitGroup) {
    defer wg.Done()
}

我之前使用过pthread_create,它在某些情况下确实无法创建线程。在这种情况下,上述go myThread(wg) 是否可能无法启动和/或运行wg.Done()如果例程的其余部分行为正确?如果是这样,将报告什么以及如何捕获错误?我担心wg 中可能出现泄漏,原因是线程创建后wg.Add(1)。 (当然可以在函数中使用wg.Add(1),但这会导致增量和主程序等待之间的其他竞争)。

我已经阅读了大量关于 go-routines 的文档,并且没有提到任何地方的调度或线程创建失败。如果我创建数十亿个线程并耗尽簿记空间会怎样? go-routine 是否仍然有效并且线程仍然被创建?

【问题讨论】:

  • 为什么是-1?
  • 这就像问“if 语句会失败吗?例如if true { }?”没有什么能保证 go 例程会运行,但 go 语句本身不能“失败”。
  • 感谢@Volker,但您发现它与其他语言略有不同。你能告诉我我们是否能弄清楚 go 例程不会运行吗?我担心 WaitGroup 泄漏,以防它不运行。
  • 不,你不能“找出来”。如果你的 goroutine 做了一些无休止的阻塞,你就不会点击 wg.Done。但你不会“泄漏”。你所拥有的只是一个有缺陷的程序。但我不确定我是否理解你的问题。如果你希望你的主 goroutine 传递 wg.Wait,你必须确保你的 myThread 以一种或另一种方式返回。
  • @Volker 问题是我在创建 go-routine 后在主线程中执行 wg.Add(1),然后在主线程中我为所有人执行 wg.Wait()线程退出。如果根本没有安排例程,则不会有递减(wg.Done()),因此主线程将无限期等待。

标签: multithreading go concurrency


【解决方案1】:

我不知道有任何可能导致此操作失败的方法,如果可能,它会导致恐慌(并因此导致应用程序崩溃)。我从未见过这种情况发生,而且我知道运行 数百万 个 goroutine 的应用程序示例。唯一的限制因素是分配 goroutine 堆栈的可用内存。

go foo() 不像 pthread_create。 Goroutine 是由 Go 运行时处理的轻量级绿色线程,并计划在 OS 线程上运行。启动 goroutine 不会启动新的 OS 线程。

【讨论】:

  • 感谢@Adrian 提供的信息。有没有这方面的文件?我发现很难获得 GoLang 的标准文档。
  • 不确定你在寻找什么“标准文档”,所有 stdlib 包的语言规范和文档都可以在 golang.org 上找到。对“goroutines”进行简单的网络搜索会发现大量信息。
  • 谢谢,我可以得到规范,但它没有提到故障模式,因为它相当于我想的函数调用。有很多信息,但没有提到任何失败,所以我会假设没有失败。
  • 正确。启动 goroutine 没有失败模式。
【解决方案2】:

您的代码的问题不在于启动一个 goroutine(它本身不会“失败”)或类似的问题,而在于使用 sync.WaitGroup。您的代码有两个主要 错误

  1. 您必须在启动 goroutine 之前执行 wg.Add(1) ,否则 Done() 可能会在 Add(1) 之前执行。

  2. 必须 复制一个sync.WaitGroup。您的代码在调用 myThread() 时进行了复制。

sync.WaitGroup 的官方文档和https://golang.org/pkg/sync/#WaitGroup 中的给定示例解释了这两个问题

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-02-13
    • 2014-10-11
    • 1970-01-01
    • 2010-11-25
    • 2018-04-28
    • 1970-01-01
    • 2013-08-04
    相关资源
    最近更新 更多