Können Sie in Go sowohl Sende- als auch Empfangskanäle auswählen, ohne sie zu blockieren?

Susan Sarandon
Freigeben: 2024-10-26 22:34:31
Original
849 Leute haben es durchsucht

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

Auswahl bidirektionaler Kanäle für bedingtes Senden und Empfangen

In Go ist es möglich, gepufferte Kanäle sowohl für das Senden als auch für den Empfang einzurichten selektive Operationen basierend auf ihrer Verfügbarkeit. Stellen Sie sich das folgende Szenario vor:

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

Wir haben einen gepufferten Sendekanal s und einen ungepufferten Empfangskanal r. Es stellt sich die Frage: Können wir auf beiden Kanälen auswählen, um festzustellen, ob r Daten hat oder s nicht voll ist? Dies ahmt die Funktionalität des Folgenden nach, ohne jedoch 100 % CPU zu verbrauchen:

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

Auswahl mit einem Standardfall implementieren

Um dies zu erreichen, können wir die verwenden select-Anweisung mit einem Standardfall. Im Standardfall, wenn keiner der Kanäle bereit ist, „schlafen“ wir die Goroutine vorübergehend, um unnötigen Ressourcenverbrauch zu vermeiden.

<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)
    }
}
Nach dem Login kopieren

Warum Längen- und Kapazitätsprüfungen nicht ideal sind

Es ist wichtig, die Länge oder Kapazität eines Kanals nicht zu überprüfen, bevor Sie versuchen zu senden oder zu empfangen. Dies liegt daran, dass sich der Status des Kanals zwischen dem Zeitpunkt der Überprüfung und dem tatsächlichen Vorgang ändern kann, was möglicherweise zu unerwarteten Blockierungen führen kann. Zum Beispiel:

<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>
Nach dem Login kopieren

Das obige ist der detaillierte Inhalt vonKönnen Sie in Go sowohl Sende- als auch Empfangskanäle auswählen, ohne sie zu blockieren?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Quelle:php.cn
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Neueste Artikel des Autors
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage
Über uns Haftungsausschluss Sitemap
Chinesische PHP-Website:Online-PHP-Schulung für das Gemeinwohl,Helfen Sie PHP-Lernenden, sich schnell weiterzuentwickeln!