英文:
Does golang support global recovery?
问题
我有一个有很多goroutine的程序,我想要全局处理panic。看起来我必须在每个goroutine中添加一个recovery,有没有一种方法可以全局处理呢?
我写了一个测试程序,在main函数中添加了一个recover(),但它无法捕获其他goroutine中的崩溃:
package main
import "log"
func bug2() {
panic("bug2()")
}
func bug1() {
go bug2()
}
func main() {
defer func() {
if r := recover(); r != nil {
log.Println("catched")
}
}()
bug1()
select {}
}
这里有什么最佳实践吗?
英文:
I have a program with lots of goroutines, and I want to handle the panic globally. It looks like I have to add a recovery in each of the goroutines, is there a way to do it globally?
I wrote a test program and I add a recover() in main, but it won't catch the crash in other goroutines:
package main
import "log"
func bug2() {
panic("bug2()")
}
func bug1() {
go bug2()
}
func main() {
defer func() {
if r := recover(); r != nil {
log.Println("catched")
}
}()
bug1()
select {}
}
What's the best practice here?
答案1
得分: 1
golang不支持全局的recover()
函数。recover()
只能在当前函数或当前goroutine中执行。
第一个示例代码中,bug2()
函数中使用了defer
语句来捕获panic,并在recover()
函数返回非nil值时打印日志。然后,在bug1()
函数中启动了一个新的goroutine来调用bug2()
函数。最后,在main()
函数中使用sync.WaitGroup
来等待goroutine执行完毕。
第二个示例代码中,bug2()
函数中直接panic。然后,在bug1()
函数中创建了一个新的sync.WaitGroup
,并在匿名函数中使用defer
语句来捕获panic,并在recover()
函数返回非nil值时打印日志。在匿名函数中调用了bug2()
函数,并使用sync.WaitGroup
等待goroutine执行完毕。
两个示例代码的运行结果分别是:
第一个示例代码的运行结果是:
2022/09/13 11:33:33 bug2 catched
第二个示例代码的运行结果是:
2022/09/13 11:44:21 bug1 catched
英文:
golang not support global recover()
. Recover() can only be executed in the current function or current goroutine.
package main
import (
"log"
"sync"
)
var wg sync.WaitGroup
func bug2() {
defer func() {
if r := recover(); r != nil {
log.Println("bug2 catched")
}
wg.Done()
}()
panic("bug2()")
}
func bug1() {
go bug2()
}
func main() {
wg.Add(1)
bug1()
wg.Wait()
}
result:
➜ src git:(master) ✗ go run recover_global_example.go
2022/09/13 11:33:33 bug2 catched
Or:
package main
import (
"log"
"sync"
)
func bug2() {
panic("bug2()")
}
func bug1() {
var wg sync.WaitGroup
wg.Add(1)
go func() {
defer func() {
if r := recover(); r != nil {
log.Println("bug1 catched")
}
wg.Done()
}()
bug2()
}()
wg.Wait()
}
func main() {
bug1()
}
retult:
➜ src git:(master) ✗ go run recover_global_example3.go
2022/09/13 11:44:21 bug1 catched
答案2
得分: 1
有没有一种全局的方法来做到这一点?
没有,不能从代码内部实现。
如果你真的需要这样(而不是修复导致程序崩溃的错误),你可以通过某种监控程序来启动你的Go程序,在出现故障时重新启动它。
英文:
> is there a way to do it globally?
No, not from inside code.
If you really need that (instead of fixing bugs that panic): Start your Go program via some monitor which restarts it in case of failure.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论