Rumah  >  Artikel  >  pembangunan bahagian belakang  >  Mengapa Saluran Go Menyebabkan Kebuntuan dan Bagaimana Kami Boleh Menghalangnya?

Mengapa Saluran Go Menyebabkan Kebuntuan dan Bagaimana Kami Boleh Menghalangnya?

Mary-Kate Olsen
Mary-Kate Olsenasal
2024-11-02 09:50:03394semak imbas

Why Do Go Channels Cause Deadlocks and How Can We Prevent Them?

Saluran Go dan Kebuntuan: Memahami Isu Penyekatan

Apabila bekerja dengan saluran Go, kebuntuan boleh timbul jika penyegerakan yang betul tidak dipastikan. Pertimbangkan contoh berikut:

<code class="go">func main() {
    c1 := make(chan int)
    c2 := make(chan int)

    // Create two goroutines that ping-pong values between channels
    go func() {
        for i := range c1 {
            println("G1 got", i)
            c2 <- i
        }
    }()

    go func() {
        for i := range c2 {
            println("G2 got", i)
            c1 <- i
        }
    }()

    // Send an initial value to start the chain
    c1 <- 1

    // Wait for a long time to observe the ping-ponging behavior
    time.Sleep(1000000000 * 50)
}</code>

Kod ini berjaya mencetak nilai selama-lamanya sehingga fungsi utama keluar. Walau bagaimanapun, jika nilai lain dihantar ke salah satu saluran, kebuntuan berlaku:

<code class="go">func main() {
    c1 := make(chan int)
    c2 := make(chan int)

    // Create two goroutines to ping-pong values between channels
    go func() {
        for i := range c1 {
            println("G1 got", i)
            c2 <- i
        }
    }()

    go func() {
        for i := range c2 {
            println("G2 got", i)
            c1 <- i
        }
    }()

    // Send an initial value to start the chain
    c1 <- 1

    // Wait for a short time
    time.Sleep(1000000000 * 1)

    // Send another value to the channel
    c1 <- 2

    // Wait for a long time to observe the issue
    time.Sleep(1000000000 * 50)
}</code>

Dalam kes ini, output tersekat selepas menghantar nilai "2":

G1 got 1
G2 got 1
G1 got 1
G2 got 1
G1 got 2

Isu ini berlaku kerana goroutine sedang menunggu antara satu sama lain untuk menerima nilai daripada saluran masing-masing. Oleh itu, kedua-dua goroutine tidak boleh maju, dan kebuntuan berlaku.

Untuk mengelakkan kebuntuan, pastikan saluran disegerakkan dengan betul. Satu pendekatan ialah menggunakan saluran buffered dengan kapasiti bukan sifar, seperti dalam contoh berikut:

<code class="go">// ... (Same code as before)
c1 := make(chan int, 1) // Buffered channel with capacity of 1
c2 := make(chan int, 1)</code>

Dengan saluran buffered, satu goroutine boleh menghantar nilai walaupun goroutine yang lain belum menerima yang sebelumnya. satu. Ini membantu mengelakkan kebuntuan dalam situasi seperti yang diterangkan.

Atas ialah kandungan terperinci Mengapa Saluran Go Menyebabkan Kebuntuan dan Bagaimana Kami Boleh Menghalangnya?. 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