我计划实现一个go-routine并有一个sync.WaitGroup
来同步已创建的go例程的结束。我主要使用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是否仍然可以工作并且仍然可以创建线程?
答案 0 :(得分:3)
我不知道有任何可能的方法导致失败,如果可能,它会导致恐慌(并因此导致应用程序崩溃)。我从来没有见过它,我知道运行数百万 goroutines的应用程序的例子。唯一的限制因素是可用内存来分配goroutine堆栈。
go foo()
与pthread_create
不同。 Goroutines是由Go运行时处理的轻量级绿色线程,并计划在OS线程上运行。启动goroutine不会启动新的OS线程。
答案 1 :(得分:0)
您的代码的问题不在于启动goroutine(本身不能“失败”)或类似但是在使用sync.WaitGroup
时。您的代码有两个主要 错误:
您必须在启动goroutine之前执行wg.Add(1)
,否则Done()
可能会在Add(1)
之前执行。
您必须 不复制sync.WaitGroup。您的代码在调用myThread()时会复制。
这两个问题都在sync.WaitGroup和https://golang.org/pkg/sync/#WaitGroup中的给定示例的官方文档中进行了解释