Rumah >pembangunan bahagian belakang >Golang >Sebuah goroutine yang mencetak nombor ganjil dan genap secara bergilir-gilir tersekat dalam kebuntuan

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

王林
王林ke hadapan
2024-02-13 16:00:101252semak imbas

交替打印奇数和偶数的 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()
}

[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
}

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!

Kenyataan:
Artikel ini dikembalikan pada:stackoverflow.com. Jika ada pelanggaran, sila hubungi admin@php.cn Padam