Mengapa Melepasi Nilai Daripada Penunjuk Menyebabkan Kebuntuan dalam Saluran Go?

Barbara Streisand
Lepaskan: 2024-10-28 21:44:02
asal
296 orang telah melayarinya

Why Does Passing Values Instead of Pointers Cause Deadlock in Go Channels?

Ralat Kebuntuan dalam Saluran Go

Dalam Go, saluran menyediakan cara komunikasi antara goroutine. Walau bagaimanapun, penggunaan saluran yang tidak betul boleh menyebabkan kebuntuan, di mana goroutin disekat selama-lamanya.

Satu punca biasa kebuntuan dengan saluran ialah apabila menghantar jenis nilai dan bukannya penunjuk dalam fungsi goroutine. Ini kerana Go melepasi jenis nilai mengikut nilai, bermakna salinan nilai dibuat.

Pertimbangkan contoh ini:

<code class="go">import (
    "fmt"
    "sync"
)

func push(c chan int, wg sync.WaitGroup) {
    for i := 0; i < 5; i++ {
        c <- i
    }
    wg.Done()
}

func pull(c chan int, wg sync.WaitGroup) {
    for i := 0; i < 5; i++ {
        result, ok := <-c
        fmt.Println(result, ok)
    }
    wg.Done()
}

func main() {
    var wg sync.WaitGroup
    wg.Add(2)
    c := make(chan int)

    go push(c, wg)
    go pull(c, wg)

    wg.Wait()
}</code>
Salin selepas log masuk

Menjalankan program mengakibatkan ralat jalan buntu:

    0 true
    1 true
    2 true
    3 true
    4 true
    throw: all goroutines are asleep - deadlock!
Salin selepas log masuk

Kebuntuan berlaku kerana WaitGroup dihantar ke fungsi tolak dan tarik sebagai nilai. Apabila WaitGroup dikemas kini dalam salah satu goroutine, perubahan tidak ditunjukkan dalam goroutine yang lain kerana ia mempunyai salinan nilai.

Untuk menyelesaikan kebuntuan, kita perlu menghantar WaitGroup sebagai penunjuk, yang memastikan kedua-dua goroutine beroperasi pada contoh WaitGroup yang sama.

Berikut ialah versi kod yang diperbetulkan:

<code class="go">import (
    "fmt"
    "sync"
)

func push(c chan int, wg *sync.WaitGroup) {
    for i := 0; i < 5; i++ {
        c <- i
    }
    wg.Done()
}

func pull(c chan int, wg *sync.WaitGroup) {
    for i := 0; i < 5; i++ {
        result, ok := <-c
        fmt.Println(result, ok)
    }
    wg.Done()
}

func main() {
    var wg sync.WaitGroup
    wg.Add(2)
    c := make(chan int)

    go push(c, &wg)
    go pull(c, &wg)

    wg.Wait()
}</code>
Salin selepas log masuk

Atas ialah kandungan terperinci Mengapa Melepasi Nilai Daripada Penunjuk Menyebabkan Kebuntuan dalam Saluran Go?. 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!