Rumah  >  Artikel  >  pembangunan bahagian belakang  >  Mengapakah `recover()` Gagal Mengendalikan Panik dalam Go Routines?

Mengapakah `recover()` Gagal Mengendalikan Panik dalam Go Routines?

Susan Sarandon
Susan Sarandonasal
2024-11-06 20:01:03799semak imbas

Why Does `recover()` Fail to Handle Panics in Go Routines?

Mengendalikan Panik dalam Rutin Pergi

Rutin Go memberikan keselarasan dalam program Go, tetapi panik dalam rutin ini boleh menimbulkan cabaran. Untuk pulih daripada panik, fungsi recover() biasanya digunakan. Walau bagaimanapun, terdapat keadaan di mana recover() gagal beroperasi seperti yang dijangkakan dalam goroutines.

Memahami Kegagalan Pemulihan dalam Rutin Pergi

Pertimbangkan blok kod berikut:

func main() {
    done := make(chan int64)
    defer fmt.Println("Graceful End of program")
    defer func() {
     r := recover()
     if _, ok := r.(error); ok {
        fmt.Println("Recovered")
     }
    }()

    go handle(done)
    for {
        select{
        case <- done:
        return
        }
    } 
}

func handle(done chan int64) {
    var a *int64
    a = nil

    fmt.Println(*a)
    done <- *a
}

Kod ini cuba pulih daripada panik dalam goroutine menggunakan fungsi tertunda dalam fungsi utama. Bagaimanapun, ia gagal memulihkan panik. Sebaliknya, blok kod berikut beroperasi seperti yang dijangkakan:

func main() {
    done := make(chan int64)
    defer fmt.Println("Graceful End of program")
    defer func() {
     r := recover()
     if _, ok := r.(error); ok {
        fmt.Println("Recovered")
     }
    }()

    handle(done)
    for {
        select{
        case <- done:
        return
        }
    } 
}

func handle(done chan int64) {
    var a *int64
    a = nil

    fmt.Println(*a)
    done <- *a
}

Menyelesaikan Isu Pemulihan

Kunci untuk memahami tingkah laku ini terletak pada sifat goroutin. recover() hanya boleh pulih daripada panik yang berlaku dalam goroutine yang sama di mana ia dipanggil. Dari blog Go:

Proses meneruskan timbunan sehingga semua fungsi dalam goroutine semasa telah kembali, pada ketika itu program ranap

Untuk mengendalikan panik dalam goroutine, seseorang perlu menggunakan fungsi pemulihan tertunda dalam goroutine itu sendiri.

func handle(done chan int64) {
    defer func() {
        if r := recover(); r != nil {
            if _, ok := r.(error); ok {
                fmt.Println("Recovered in goroutine")
            }
        }
    }()

    var a *int64
    a = nil

    fmt.Println(*a)
    done <- *a
}

Dengan meletakkan fungsi pemulihan dalam goroutine, seseorang boleh memintas panik dan mengendalikannya dengan sewajarnya.

Atas ialah kandungan terperinci Mengapakah `recover()` Gagal Mengendalikan Panik dalam Go Routines?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn