Sebuah goroutine yang mencetak nombor ganjil dan genap secara bergilir-gilir tersekat dalam kebuntuan

王林
Lepaskan: 2024-02-13 16:00:10
ke hadapan
1204 orang telah melayarinya

交替打印奇数和偶数的 goroutine 陷入死锁

"Groutine yang mencetak nombor ganjil dan genap secara bergantian terperangkap dalam kebuntuan" adalah masalah biasa dalam pengaturcaraan serentak. Apabila menggunakan goroutine untuk operasi serentak, jika tiada mekanisme penyegerakan yang betul, ia boleh menyebabkan kebuntuan dengan mudah. Kebuntuan ialah keadaan di mana dua atau lebih proses (atau goroutine) tidak dapat meneruskan pelaksanaan kerana mereka sedang menunggu satu sama lain untuk melepaskan sumber. Artikel ini akan memperkenalkan punca masalah ini dan menyediakan penyelesaian untuk membantu pembangun lebih memahami masalah kebuntuan dalam pengaturcaraan serentak.

Isi soalan

Saya sedang belajar golang. Saya ingin menyemak cara saluran golang berfungsi. Saya mencipta program di mana dua goroutine akan mencetak nombor ganjil dan genap secara bergantian. Walaupun program mencetak dengan betul, ia masih menunjukkan ralat kebuntuan pada penghujungnya. Tidak jelas daripada mesej ralat apa yang menyebabkan masalah ini.

func main() {
    even := make(chan bool)
    odd := make(chan bool)
    go func() {
        defer close(odd)
        for i := 0; i <= 10; i += 2 {
            <-even
            print("even ====>")
            println(i)
            odd <- true
        }
    }()
    var wait sync.waitgroup
    wait.add(1)
    go func() {
        for i := 1; i <= 10; i += 2 {
            _, ok := <-odd
            if !ok {
                wait.done()
                return
            }
            print("odd ====>")
            println(i)
            even <- true
        }
    }()
    even <- true
    wait.wait()
}
Salin selepas log masuk

[sunting] Terima kasih semua atas balasan anda. Saya menulis kod berikut untuk menyelesaikan masalah.

func main() {
    even := make(chan bool)
    odd := make(chan bool)
    done := make(chan bool)
    //var wait sync.WaitGroup
    //wait.Add(2)
    go func() {
        for i := 0; i <= 10; i += 2 {
            <-even
            print("Even ====>")
            println(i)
            odd <- true
        }
        close(odd)
        close(even)
        done <- true
        // wait.Done()
    }()
    go func() {
        for i := 1; ; i += 2 {
            _, ok := <-odd
            if !ok {
                //wait.Done()
                return
            }
            print("Odd ====>")
            println(i)
            select {
            case even <- true:
            case <-done:
                return
            }
        }
    }()
    even <- true
    //wait.Wait()
    <-done
}
Salin selepas log masuk

Penyelesaian

Masalah boleh diselesaikan dengan cara berikut

  1. Tanggalkan gofunc kedua untuk penutup (baris 20)
  2. selecting 写入 even (baris 28)

Atas ialah kandungan terperinci Sebuah goroutine yang mencetak nombor ganjil dan genap secara bergilir-gilir tersekat dalam kebuntuan. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Label berkaitan:
sumber:stackoverflow.com
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
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!