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

Susan Sarandon
Lepaskan: 2024-11-06 20:01:03
asal
879 orang telah melayarinya

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
}
Salin selepas log masuk

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
}
Salin selepas log masuk

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
}
Salin selepas log masuk

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!

sumber:php.cn
Kenyataan Laman Web ini
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
Artikel terbaru oleh pengarang
Tutorial Popular
Lagi>
Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan