为了账号安全,请及时绑定邮箱和手机立即绑定

如果另一个发生崩溃,你如何保持戈鲁丁的运行?

如果另一个发生崩溃,你如何保持戈鲁丁的运行?

Go
PIPIONE 2022-08-15 10:54:21
我一直试图找到一些可以回答这个问题的东西,但我找不到任何谈论它的东西。假设我在Go中有一个函数,它是这样的:func main() {    // assume this wrapped in a waitgroup or something     // so that it doesnt exit    go queue.ConsumeAndDoSomething()    go api.StartServer()}我这里有两个goroutine,它们做完全不同的事情,如果另一个崩溃/恐慌,理想情况下应该继续运行。如果队列操作失败,API 服务器应该会受到影响,反之亦然。我不确定这是否可能(甚至推荐)。有没有一种干净的方法可以做到这一点,或者一旦goroutine恐慌,整个程序是否应该退出?
查看完整描述

2 回答

?
偶然的你

TA贡献1841条经验 获得超3个赞

您必须使用内置的 recover() 函数从 panic 中恢复,并且必须在延迟函数中调用它。


假设您有一个可能会惊慌失措的函数:


func doPanic() {

    log.Println("about to panic")

    panic("test")

}

创建一个帮助程序函数,以启动一个函数作为 goroutine “protected”(来自 panics):


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

...


查看完整回答
反对 回复 2022-08-15
?
青春有我

TA贡献1784条经验 获得超8个赞

如果您希望其他goroutine不受影响,则每个goroutine必须推迟呼叫以从潜在的恐慌中恢复过来。recover


而不是


go queue.ConsumeAndDoSomething()

您应该使用


go func(){

    defer func() {

            if r := recover(); r != nil {

                log.Error("goroutine paniqued: ", r)

            }

        }()

    queue.ConsumeAndDoSomething()

}() 


查看完整回答
反对 回复 2022-08-15
  • 2 回答
  • 0 关注
  • 96 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号