如果另一个 goroutines 崩溃了,你如何保持 goroutines 运行?
How do you keep goroutines running if another one crashes?
我一直在努力寻找可以回答这个问题的东西,但我找不到任何关于它的东西。
假设我在 Go 中有一个函数是这样的:
func main() {
// assume this wrapped in a waitgroup or something
// so that it doesnt exit
go queue.ConsumeAndDoSomething()
go api.StartServer()
}
我这里有两个 goroutine,它们做完全不同的事情,理想情况下,如果另一个 crashes/panics,一个应该保持 运行。如果队列操作失败,API 服务器应该受到影响,反之亦然。
我不确定这是否可行(或什至推荐)。有没有一种干净的方法可以做到这一点,或者整个程序应该在 goroutine 恐慌时退出?
如果您希望其他 goroutine 不受影响,则每个 goroutine 必须推迟 recover
调用以从潜在的 panic 中恢复。
而不是
go queue.ConsumeAndDoSomething()
你应该使用
go func(){
defer func() {
if r := recover(); r != nil {
log.Error("goroutine paniqued: ", r)
}
}()
queue.ConsumeAndDoSomething()
}()
您必须使用内置的 recover()
function to recover from panics, and you have to call it in a deferred 函数。
假设你有一个函数可能会崩溃:
func doPanic() {
log.Println("about to panic")
panic("test")
}
创建一个辅助函数来启动一个函数作为 goroutine “受保护”(避免恐慌):
func protect(f func()) {
defer func() {
if err := recover(); err != nil {
log.Printf("Recovered: %v", err)
}
}()
f()
}
并像这样使用它:
func main() {
go protect(doPanic)
for {
time.Sleep(time.Second)
fmt.Println("tick")
}
}
此测试应用程序将输出:
2021/03/04 14:12:31 about to panic
2021/03/04 14:12:31 Recovered: test
tick
tick
tick
...
参见相关问题:Generic panic recovering in go programs
我一直在努力寻找可以回答这个问题的东西,但我找不到任何关于它的东西。
假设我在 Go 中有一个函数是这样的:
func main() {
// assume this wrapped in a waitgroup or something
// so that it doesnt exit
go queue.ConsumeAndDoSomething()
go api.StartServer()
}
我这里有两个 goroutine,它们做完全不同的事情,理想情况下,如果另一个 crashes/panics,一个应该保持 运行。如果队列操作失败,API 服务器应该受到影响,反之亦然。
我不确定这是否可行(或什至推荐)。有没有一种干净的方法可以做到这一点,或者整个程序应该在 goroutine 恐慌时退出?
如果您希望其他 goroutine 不受影响,则每个 goroutine 必须推迟 recover
调用以从潜在的 panic 中恢复。
而不是
go queue.ConsumeAndDoSomething()
你应该使用
go func(){
defer func() {
if r := recover(); r != nil {
log.Error("goroutine paniqued: ", r)
}
}()
queue.ConsumeAndDoSomething()
}()
您必须使用内置的 recover()
function to recover from panics, and you have to call it in a deferred 函数。
假设你有一个函数可能会崩溃:
func doPanic() {
log.Println("about to panic")
panic("test")
}
创建一个辅助函数来启动一个函数作为 goroutine “受保护”(避免恐慌):
func protect(f func()) {
defer func() {
if err := recover(); err != nil {
log.Printf("Recovered: %v", err)
}
}()
f()
}
并像这样使用它:
func main() {
go protect(doPanic)
for {
time.Sleep(time.Second)
fmt.Println("tick")
}
}
此测试应用程序将输出:
2021/03/04 14:12:31 about to panic
2021/03/04 14:12:31 Recovered: test
tick
tick
tick
...
参见相关问题:Generic panic recovering in go programs