返回 vs. Goexit 用于 goroutine

huangapple go评论82阅读模式
英文:

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内部的函数调用中时。在标准库中,测试包在诸如FailNowSkipNow的函数中使用它来立即结束当前的测试。一般来说,你应该正常返回你的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...
}()

huangapple
  • 本文由 发表于 2015年7月27日 23:28:03
  • 转载请务必保留本文链接:https://go.coder-hub.com/31657129.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定