Maison >développement back-end >Golang >Comment sélectionner simultanément un canal d'envoi avec tampon et un canal de réception sans tampon dans Go ?

Comment sélectionner simultanément un canal d'envoi avec tampon et un canal de réception sans tampon dans Go ?

Mary-Kate Olsen
Mary-Kate Olsenoriginal
2024-10-29 07:20:30219parcourir

How to Select on a Buffered Send and Unbuffered Receive Channel Simultaneously in Go?

Sélectionner lors d'un Go Envoyer et recevoir un canal simultanément

En Go, il est possible d'effectuer des opérations d'E/S non bloquantes sur les canaux à l'aide de l'instruction select. Cependant, une question courante se pose lorsqu'il s'agit d'un canal d'envoi tamponné (chan<-) et d'un canal de réception non tamponné (<-chan) : comment pouvez-vous sélectionner simultanément les deux canaux, en donnant la priorité au canal de réception s'il contient des données et que le canal d'envoi canal s'il a de la capacité ?

Le problème lié à la vérification de la longueur/capacité du canal

Une approche courante consiste à vérifier la longueur ou la capacité des canaux avant d'envoyer ou de recevoir. Cependant, cela n'est pas fiable car l'état du canal peut changer entre la vérification et l'opération suivante :

<code class="go">if len(r) > 0 {
    // Optionally execute other code

    r <- v  // May block if another goroutine received from r in the meantime
}</p>
<h3>La solution : cas par défaut avec temporisation</h3>
<p>Pour résoudre ce problème, vous pouvez utilisez une instruction select avec un cas par défaut qui inclut un court délai. Cela évite une utilisation excessive du CPU tout en vous permettant de réessayer l'opération si les deux canaux ne sont pas prêts :</p>
<pre class="brush:php;toolbar:false"><code class="go">s := make(chan<- int, 5)
r := make(<-chan int)

for {
    v := valueToSend()
    select {
    case s <- v:
        fmt.Println("Sent value:", v)
    case vr := <-r:
        fmt.Println("Received:", vr)
    default: // If none are ready, delay execution
        time.Sleep(time.Millisecond * 1)
    }
}</code>

En ajoutant le cas par défaut, le programme ne bloquera que pendant une courte période si les deux canaux ne sont pas prêts, permettant aux ressources CPU d'être libérées en attendant qu'un canal soit disponible.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn