Maison > développement back-end > Golang > le corps du texte

Pouvez-vous sélectionner les canaux d'envoi et de réception dans Go, sans blocage ?

Susan Sarandon
Libérer: 2024-10-26 22:34:31
original
849 Les gens l'ont consulté

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

Sélection des canaux bidirectionnels pour l'envoi et la réception conditionnels

Dans Go, il est possible de configurer des canaux mis en mémoire tampon pour l'envoi et la réception, permettant opérations sélectives en fonction de leur disponibilité. Considérons le scénario suivant :

<code class="go">s := make(chan<- int, 5)
r := make(<-chan int)
Copier après la connexion

Nous avons un canal d'envoi tamponné s et un canal de réception non tamponné r. La question se pose : peut-on sélectionner sur les deux canaux pour déterminer si r contient des données ou si s n'est pas plein ? Cela imite les fonctionnalités suivantes, mais sans consommer 100 % du processeur :

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

Implémentation de Select avec un cas par défaut

Pour y parvenir, nous pouvons utiliser le instruction select avec un cas par défaut. Dans le cas par défaut, si aucun des deux canaux n'est prêt, nous « mettons en veille » temporairement la goroutine pour éviter une consommation inutile de ressources.

<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)
    }
}
Copier après la connexion

Pourquoi les contrôles de longueur et de capacité ne sont pas idéaux

Il est crucial d'éviter de vérifier la longueur ou la capacité d'un canal avant de tenter d'envoyer ou de recevoir. En effet, l'état du canal peut changer entre le moment de la vérification et le fonctionnement réel, conduisant potentiellement à un blocage inattendu. Par exemple :

<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>
Copier après la connexion

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!

source:php.cn
Déclaration de ce site Web
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
Derniers articles par auteur
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal
À propos de nous Clause de non-responsabilité Sitemap
Site Web PHP chinois:Formation PHP en ligne sur le bien-être public,Aidez les apprenants PHP à grandir rapidement!