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

Susan Sarandon
Lepaskan: 2024-10-26 22:34:31
asal
849 orang telah melayarinya

 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)
Salin selepas log masuk

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>
Salin selepas log masuk

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)
    }
}
Salin selepas log masuk

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>
Salin selepas log masuk

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!

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!