Home  >  Article  >  Backend Development  >  Why Doesn\'t a Deferred `recover` in a Caller Function Handle Panics in Child Goroutines?

Why Doesn\'t a Deferred `recover` in a Caller Function Handle Panics in Child Goroutines?

Susan Sarandon
Susan SarandonOriginal
2024-11-03 18:06:03629browse

Why Doesn't a Deferred `recover` in a Caller Function Handle Panics in Child Goroutines?

How Caller Functions Handle Panics in Child Goroutines

It was previously believed that a panic in a goroutine would terminate the program if its caller function finished before the panic occurred. However, a recent code example suggests otherwise:

<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>

Surprisingly, the program terminates regardless of whether the caller function (fun1) finishes before or after the panic in the child goroutine (fun2). This raises the question: why isn't the deferred recover mechanism in the caller function preventing the program from crashing?

The Specification's Explanation

According to the Go specification:

"While executing a function F, an explicit call to panic or a runtime panic terminates the execution of F. Any functions deferred by F are then executed as usual. Next, any deferred functions run by F's caller are run, and so on up to any deferred by the top-level function in the executing goroutine. At that point, the program is terminated and the error condition is reported, including the value of the argument to panic. This termination sequence is called panicking."

Application to the Code

Applying this specification to our code, we observe that:

  • When fun2 panics, it becomes the top-level goroutine and terminates.
  • Since fun2 does not recover from the panic, the program terminates.
  • The deferred call in fun1 is not invoked because the panic occurs in a different goroutine.

Conclusion

Therefore, it is crucial to understand that a goroutine cannot recover from a panic in another goroutine. If a child goroutine panics, only the goroutine itself can handle the panic using the defer/recover mechanism. If the child goroutine does not recover, the entire program will terminate, regardless of the status of its caller.

The above is the detailed content of Why Doesn\'t a Deferred `recover` in a Caller Function Handle Panics in Child Goroutines?. For more information, please follow other related articles on the PHP Chinese website!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn