Rumah  >  Artikel  >  pembangunan bahagian belakang  >  Bolehkah Anda Pilih pada Kedua-dua Saluran Menghantar dan Menerima dalam Go, Tanpa Menyekat?

Bolehkah Anda Pilih pada Kedua-dua Saluran Menghantar dan Menerima dalam Go, Tanpa Menyekat?

Susan Sarandon
Susan Sarandonasal
2024-10-26 22:34:31836semak imbas

 Can You Select on Both Sending and Receiving Channels in Go, Without Blocking?

Memilih pada Saluran Dwi Arah untuk Menghantar dan Menerima Bersyarat

Dalam Go, adalah mungkin untuk menyediakan saluran penimbal untuk kedua-dua penghantaran dan penerimaan, membenarkan operasi terpilih berdasarkan ketersediaannya. Pertimbangkan senario berikut:

<code class="go">s := make(chan<- int, 5)
r := make(<-chan int)

Kami mempunyai saluran hantar buffer s dan saluran terima tidak buffer r. Timbul persoalan: bolehkah kita memilih pada kedua-dua saluran untuk menentukan sama ada r mempunyai data atau s tidak penuh? Ini meniru kefungsian berikut, tetapi tanpa menggunakan 100% CPU:

<code class="go">for {
    if len(s) < cap(s) {
        // Send something
    }
    if len(r) > 0 {
        // Receive something
    }
}</code>

Melaksanakan Pilih dengan Kes Lalai

Untuk mencapai ini, kita boleh menggunakan pilih pernyataan dengan kes lalai. Dalam kes lalai, jika kedua-dua saluran tidak tersedia, kami "sleep" sementara goroutine untuk mengelakkan penggunaan sumber yang tidak perlu.

<code class="go">s := make(chan<- int, 5)
r := make(<-chan int)

for {
    v := valueToSend() // Value to be sent, evaluated upon each attempt
    select {
    case s <- v:
        fmt.Println("Sent value:", v)
    case vr := <-r:
        fmt.Println("Received:", vr)
    default: // Neither channel is ready, pause briefly
        time.Sleep(time.Millisecond * 1)
    }
}

Mengapa Semakan Panjang dan Kapasiti Tidak Ideal

Adalah penting untuk mengelak menyemak panjang atau kapasiti saluran sebelum cuba menghantar atau menerima. Ini kerana keadaan saluran boleh berubah antara masa pemeriksaan dan operasi sebenar, yang berpotensi membawa kepada penyekatan yang tidak dijangka. Contohnya:

<code class="go">if len(r) > 0 {
    // r is ready to receive

    // Other code...

    r <-  // This may block if another goroutine has already received from r!
}</code>

Atas ialah kandungan terperinci Bolehkah Anda Pilih pada Kedua-dua Saluran Menghantar dan Menerima dalam Go, Tanpa Menyekat?. 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