首页 > 后端开发 > Golang > 调用者函数可以从 Go 子 Goroutines 中的 Panic 中恢复吗?

调用者函数可以从 Go 子 Goroutines 中的 Panic 中恢复吗?

Barbara Streisand
发布: 2024-10-29 08:41:30
原创
482 人浏览过

Can a Caller Function Recover from Panics in Child Goroutines in Go?

从 Go 中的子 Goroutine 恐慌中恢复

在最近的编程工作中,一个基本假设受到了挑战:调用者函数的能力从子 goroutine 的恐慌中恢复过来。尽管传统观点认为并非如此,但我们发现,当子 goroutine 陷入恐慌时,调用者的延迟恢复机制无法阻止整个程序终止。

为了说明这种令人费解的行为,请考虑以下代码:

<code class="go">func fun1() {
    fmt.Println("fun1 started")
    defer func() {
        if err := recover(); err != nil {
            fmt.Println("recover in func1")
        }
    }()

    go fun2()

    time.Sleep(10 * time.Second) // wait for the boom!
    fmt.Println("fun1 ended")
}

func fun2() {
    fmt.Println("fun2 started")

    time.Sleep(5 * time.Second)
    panic("fun2 booom!")

    fmt.Println("fun2 ended")
}</code>
登录后复制

有趣的是,无论 fun1 在 fun2 发生恐慌之前还是之后结束,fun1 中的延迟恢复机制都无效,导致程序立即终止。

背后的原因失败

Go 规范对这种非常规行为进行了澄清:

在执行函数 F 时,对恐慌的显式调用或运行时恐慌会终止 F 的执行。 F 推迟的函数然后照常执行。 接下来,由 F 的调用者运行的任何延迟函数都会运行,依此类推,直到执行 Goroutine 中的顶级函数所延迟的任何函数。 此时,程序终止并报告错误情况,包括panic的参数值。

在这种情况下,fun2代表在其各自的goroutine中执行的顶级函数。由于 fun2 缺乏恢复机制,程序会在发生恐慌时终止,而忽略 fun1 或其前辈中任何延迟的恢复尝试。

这种行为强调了一个关键区别:goroutine 无法从源自以下的恐慌中恢复:一个单独的 goroutine。因此,fun1 中的延迟恢复变得徒劳,因为 fun2 中的恐慌有效地终止了 goroutine 以及任何后续的恢复工作。

以上是调用者函数可以从 Go 子 Goroutines 中的 Panic 中恢复吗?的详细内容。更多信息请关注PHP中文网其他相关文章!

来源:php.cn
本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
作者最新文章
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板