Bagaimana Menghentikan Rutin Pergi dengan Anggun: Panduan Mengelakkan Kebuntuan dan Proses Tidak Bertindak Balas?

Linda Hamilton
Lepaskan: 2024-10-28 14:11:02
asal
535 orang telah melayarinya

 How to Gracefully Stop a Go Routine: A Guide to Avoiding Deadlocks and Unresponsive Processes?

Cara Menghentikan Rutin Pergi dengan Anggun

Dalam Go, goroutine memberikan keselarasan ringan, tetapi mungkin mencabar untuk menamatkannya dengan anggun. Soalan ini menangani keperluan untuk menghantar isyarat kepada goroutine untuk menghentikan pelaksanaannya.

Kod yang disediakan menunjukkan percubaan untuk menghentikan goroutine dengan menetapkan bendera boolean (terlaluLambat) kepada benar. Walau bagaimanapun, pendekatan ini bermasalah kerana membaca daripada saluran menyekat goroutine.

Penyelesaian 1: Menggunakan Saluran Tambahan

Penyelesaian melibatkan penggunaan saluran kedua (Terlalu Lewat) untuk menyampaikan isyarat berhenti. Saluran ini kekal terbuka walaupun goroutine tidak membaca secara aktif daripadanya.

<code class="go">func main() {
    tooLate := make(chan struct{}) // Unbuffered channel for stop signal
    proCh := make(chan string)

    go func() {
        for {
            fmt.Println("working")
            time.Sleep(1 * time.Second)
            select {
            case <-tooLate:
                fmt.Println("stopped")
                return
            case proCh <- "processed": // Non-blocking send
            default: // Allows the goroutine to continue without blocking
            }
            fmt.Println("done here")
        }
    }()

    select {
    case proc := <-proCh:
        fmt.Println(proc)
    case <-time.After(1 * time.Second):
        fmt.Println("too late")
        close(tooLate) // Signal to goroutine to stop
    }

    time.Sleep(4 * time.Second)
    fmt.Println("finish\n")
}</code>
Salin selepas log masuk

Dalam penyelesaian ini, apabila had masa tamat, saluran tooLate ditutup, yang menyebabkan goroutine keluar dari pernyataan pilih penyekatnya dan kembali.

Penyelesaian 2: Menggunakan sync.Cond

Sebagai alternatif, anda boleh menggunakan jenis sync.Cond untuk melaksanakan mekanisme isyarat yang lebih canggih. Berikut ialah contoh:

<code class="go">func main() {
    var stopped bool
    cond := sync.NewCond(new(sync.Mutex))

    go func() {
        for {
            cond.L.Lock()
            defer cond.L.Unlock()

            if stopped {
                fmt.Println("stopped")
                return
            }
            fmt.Println("working")
            cond.Wait() // Wait for the signal to stop
        }
    }()

    time.Sleep(1 * time.Second)
    cond.Signal() // Send the stop signal

    time.Sleep(4 * time.Second)
    fmt.Println("finish\n")
}</code>
Salin selepas log masuk

Dengan pendekatan ini, goroutine menunggu pada kaedah cond.Tunggu() sehingga ia menerima isyarat daripada cond.Signal().

Atas ialah kandungan terperinci Bagaimana Menghentikan Rutin Pergi dengan Anggun: Panduan Mengelakkan Kebuntuan dan Proses Tidak Bertindak Balas?. 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
Tentang kita Penafian Sitemap
Laman web PHP Cina:Latihan PHP dalam talian kebajikan awam,Bantu pelajar PHP berkembang dengan cepat!