go - 如果另一个 goroutines 崩溃了,你如何保持 goroutines 运行?
问题描述
我一直在努力寻找可以回答这个问题的东西,但我找不到任何可以谈论它的东西。
假设我在 Go 中有一个函数,它是这样的:
func main() {
// assume this wrapped in a waitgroup or something
// so that it doesnt exit
go queue.ConsumeAndDoSomething()
go api.StartServer()
}
我在这里有两个 goroutines 做完全不同的事情,如果另一个崩溃/恐慌,一个理想情况下应该继续运行。如果队列操作失败,API 服务器应该会受到影响,反之亦然。
我不确定这是否可能(甚至推荐)。有没有一种干净的方法可以做到这一点,或者一旦 goroutine 发生恐慌,整个程序是否应该退出?
解决方案
您必须使用内置recover()
函数从恐慌中恢复,并且必须在延迟函数中调用它。
假设您有一个可能会恐慌的函数:
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
...
请参阅相关问题:Go 程序中的通用恐慌恢复
推荐阅读
- c# - Linq 到字典
> 具有 Null 值 - javascript - 如何为同一页面上的两个不同帖子创建两个不同的搜索表单?
- css - 仅当子项没有特定属性而不使用 jquery 时才将 css 规则添加到父项
- css - 乘法-x 的 CSS 代码不能作为 content 属性的值
- c# - 如何在 ListView 绑定中创建/注册视图/vewmodel 的多个实例?
- xaml - 是否可以创建多平台自定义用户控件而无需在 Xamarin.Forms 中使用自定义呈现?
- excel - 有没有办法从模块名称的末尾删除数字?
- istio - 使用 Traffic Director 创建的负载平衡器缺少 Stackdriver 指标
- android - 无法在 Ubuntu 16 32 位上使用 gradle 5.5.1 构建 Android APK
- android - Workspace ONE Android 客户端 SDK 引发异常“airwatch mdm 服务的空响应”