英文:
Return vs. Goexit for goroutines
问题
我做了一些调查,但没有找到什么令人满意的结果,所以我想问一下:在退出 goroutine 时,使用 return 还是 runtime.Goexit 有什么最佳实践或优缺点?到目前为止,在一些测试中,我只发现如果你正在使用 waitgroups,它可能不会调用 Done 函数。
关于 waitgroups(如果感兴趣):在我所拥有的一个代码库中进行了一些快速测试,我创建了一个匿名函数作为 goroutine 来测试一个应该在 goroutine 中运行的方法。我尝试使用 defer 在函数调用 runtime.Goexit 时调用 wg.Done(),但它没有起作用。不确定这是预期的行为还是一个 bug。
代码示例:
go func() {
wg.Add(1)
defer wg.Done()
// 函数内容...
}()
英文:
I did some digging, but didn't really find anything satisfactory, so I'm asking: are their any best practices or pros/cons for using return vs. runtime.Goexit for exiting a goroutine? So far, the only thing I came across in some testing is that if you're using waitgroups, it may not call the Done function.
Specific to the waitgroups (if interested): in some quick testing in a codebase I have, I create an anonymous function that executes as a goroutine to test a method that's supposed to run within a goroutine. I tried to use defer to have it call wg.Done() when the function called runtime.Goexit, but it didn't work. Not sure if this is intended or a bug.
Code example:
go func() {
wg.Add(1)
defer wg.Done()
// Function goes here...
}()
答案1
得分: 11
你很少需要使用runtime.Goexit
。它用于终止当前的goroutine,当你无法从调用点返回时使用,例如当你在goroutine内部的函数调用中时。在标准库中,测试包在诸如FailNow
和SkipNow
的函数中使用它来立即结束当前的测试。一般来说,你应该正常返回你的goroutines,以保持代码清晰,并防止意外行为。
你示例中的问题是你需要在启动goroutine之前调用wg.Add
,否则你可能在Wait
调用之前执行wg.Add
调用。
wg.Add(1)
go func() {
defer wg.Done()
// 在这里编写函数...
}()
英文:
You should rarely ever need to use runtime.Goexit
. It's used to terminate the current goroutine, when you can't return from the call site, e.g. when you are in a function call within the goroutine. In the std library, the testing package uses it in functions like FailNow
and SkipNow
to immediately end the current test. In general, you should return normally from your goroutines to keep the code clear, and prevent unexpected behavior.
The problem in your example is that you need to call wg.Add
before you start the goroutine, otherwise you could reach the Wait
call before the wg.Add
calls have been executed.
wg.Add(1)
go func() {
defer wg.Done()
// Function goes here...
}()
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论