Rumah >pembangunan bahagian belakang >Golang >Bagaimanakah Saya Boleh Mengutamakan Pembatalan Konteks dalam Penyata `pilih` Go?

Bagaimanakah Saya Boleh Mengutamakan Pembatalan Konteks dalam Penyata `pilih` Go?

Mary-Kate Olsen
Mary-Kate Olsenasal
2024-12-08 11:45:11425semak imbas

How Can I Prioritize Context Cancellation in Go's `select` Statement?

Kawalan Keutamaan dalam Pernyataan Pilih Go

Dalam Go, pernyataan pilih membenarkan komunikasi tak segerak antara goroutine. Walau bagaimanapun, susunan penilaian blok kes kadangkala boleh membawa kepada keputusan yang tidak dijangka. Isu ini timbul apabila cuba mengutamakan pengendalian kes tertentu, seperti segera keluar daripada rutin apabila konteks dibatalkan.

Pertimbangkan kod berikut:

func sendRegularHeartbeats(ctx context.Context) {
    for {
        select {
        case <-ctx.Done():
            return
        case <-time.After(1 * time.Second):
            sendHeartbeat()
        }
    }
}

The Masalah:
Dalam kod ini, tujuannya adalah untuk mengutamakan pengendalian kes ctx.Done() berbanding masa.Selepas() kes. Walau bagaimanapun, disebabkan oleh perintah penilaian bukan penentuan Go, kes masa.After() kadangkala dinilai dahulu, yang membawa kepada penghantaran degupan jantung walaupun konteksnya dibatalkan.

Penyelesaian:
Penyelesaian yang dicadangkan dalam jawapan yang diterima mencadangkan menambah pernyataan pilihan bersarang dengan semakan tidak menyekat untuk ctx.Done(). Walau bagaimanapun, ini tidak menangani isu ini sepenuhnya, kerana kebarangkalian degupan jantung dihantar kekal tinggi.

Pendekatan yang lebih berkesan ialah mengutamakan pengendalian kes ctx.Done() dengan menambahkan kes lalai pada pernyataan pilihan luar:

func sendRegularHeartbeats(ctx context.Context) {
    ticker := time.NewTicker(time.Second)
    defer ticker.Stop()

    for {
        select {
        case <-ctx.Done():
            return
        default:
        }

        select {
        case <-ctx.Done():
            return
        case <-ticker.C:
            sendHeartbeat()
        }
    }
}

Ini memastikan kes ctx.Done() dinilai terlebih dahulu dalam pernyataan pilih luar, memberikannya lebih tinggi keutamaan. Jika konteks dibatalkan, rutin akan segera kembali dan tiada degupan jantung akan dihantar. Jika kes masa.After() tiba dahulu, ia akan diabaikan kerana kes lalai dalam penyataan pilih luar.

Atas ialah kandungan terperinci Bagaimanakah Saya Boleh Mengutamakan Pembatalan Konteks dalam Penyata `pilih` Go?. 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