go panic recover

Created

2024-10-28 13:23:54

Updated

2024-10-28 13:24:12

Tip

panic后会执行当前协程(main也是协程)的defer

func TestPanic(t *testing.T) {
    defer func() {
        fmt.Println("main end")
    }()
    go func() {
        defer func() {
            fmt.Println("goroutine end")
        }()
        // 协程 panic,自己的defer 执行了, 外部的defer 不会执行
        // 然后直接退出整个程序了..
        panic("goroutine panic")
    }()
    time.Sleep(3 * time.Second)
    fmt.Println("main running") // 不会执行
}
func TestPanic(t *testing.T) {
    defer func() {
        fmt.Println("main end")
    }()
    go func() {
        defer func() {
            fmt.Println("goroutine end")
            // recover 处理后, main 协程会继续正常执行
            if err := recover(); err != nil {
                fmt.Println("err:", err)
            }
        }()
        panic("goroutine panic")
    }()
    time.Sleep(3 * time.Second)
    fmt.Println("main running")
}

1 底层原理

func gopanic(e any) {
    gp := getg()  // 获取当前协程
    // ...
    for {
        d := gp._defer
        if d == nil {
            break
        }
        // ...
        if p.recovered {
            // ...
        }
    }
Back to top