Maison  >  Article  >  développement back-end  >  Comment obtenir une communication asynchrone avec la disponibilité des canaux en Go tout en minimisant l'utilisation du processeur ?

Comment obtenir une communication asynchrone avec la disponibilité des canaux en Go tout en minimisant l'utilisation du processeur ?

Patricia Arquette
Patricia Arquetteoriginal
2024-10-27 05:34:03920parcourir

How to Achieve Asynchronous Communication with Channel Readiness in Go While Minimizing CPU Utilization?

Communication asynchrone avec préparation des canaux

Dans Go, les canaux facilitent la communication simultanée entre les goroutines. Lorsqu'il s'agit de canaux d'envoi tamponnés et de canaux de réception non tamponnés, il est possible de sélectionner simultanément les deux canaux pour optimiser le flux de communication. Cet article explore l'approche pour implémenter cette fonctionnalité tout en minimisant l'utilisation du processeur.

Pour comprendre le problème, considérons le contexte suivant :

<code class="go">s := make(chan<- int, 5) // Buffered send channel
r := make(<-chan int)   // Unbuffered receive channel</code>

La question se pose de savoir s'il est possible de sélectionner sur les deux canaux tels que r soit sélectionné lorsque les données sont disponibles en lecture, et s soit sélectionné lorsque le canal n'est pas plein.

Solution

On peut y parvenir en utilisant une sélection instruction avec un cas par défaut. Étant donné que la valeur à envoyer n'est évaluée qu'une seule fois lors de l'utilisation de select, si les deux canaux ne sont pas prêts, la valeur devient obsolète. Pour éviter cela, un cas par défaut est ajouté à l'instruction de sélection, qui est exécutée si aucun des deux canaux n'est prêt. Dans ce cas par défaut, le programme se met en veille pendant une courte durée, permettant aux chaînes d'être prêtes, puis réessaye avec une valeur mise à jour.

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

for {
    v := valueToSend() // Evaluated each time we try to send
    select {
    case s <- v:
        fmt.Println("Sent value:", v)
    case vr := <-r:
        fmt.Println("Received:", vr)
    default: // If none are ready currently, we end up here
        time.Sleep(time.Millisecond * 1)
    }
}</code>

Avertissement

L'utilisation de len(r) ou de cap(s) pour vérifier l'état de préparation du canal, puis l'envoi/réception n'est pas recommandée car le canal peut changer d'état entre la vérification et la tentative d'envoi/réception.

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