Passer au contenu principal
eLearner.app
Module 7 · Leçon 2 sur 532/50 dans le cours~15 min
Leçons du module (2/5)

Channels : communication typée

Les canaux sont le mécanisme idiomatique de communication entre goroutine. Allez la philosophie (Rob Pike) :

"Ne communiquez pas en partageant la mémoire ; partagez la mémoire en communiquant."

Un canal est une file d'attente FIFO typée, de type sécurisé et sûre à utiliser concurrent. Combiné avec go, il s'agit du principal élément constitutif du Allez en compétition.

Créer, envoyer, recevoir

Go
ch := make(chan int)     // canale di int, unbuffered

go func() {
    ch <- 42             // invia (può bloccare)
}()

v := <-ch                // ricevi (può bloccare)
fmt.Println(v)           // 42

Syntaxe :

  • make(chan T) ou make(chan T, N) pour mis en mémoire tampon.
  • ch <- v envoyer.
  • v := <-ch reçoit.
  • v, ok := <-ch reçoit avec flag (ok = false si le canal est fermé ET vide).

Unbuffered : rendez-vous

Un canal non tamponné (capacité 0) bloque :

  • l'expéditeur jusqu'à ce qu'un destinataire soit prêt ;
  • le récepteur jusqu'à ce qu'un expéditeur soit prêt.

Il s'agit d'un rendez-vous synchrone : utile comme "signal" ou pour s'assurer que le la valeur a été livrée.

Buffered : file d'attente jusqu'à N

Go
ch := make(chan int, 3)
ch <- 1   // non blocca
ch <- 2   // non blocca
ch <- 3   // non blocca
ch <- 4   // BLOCCA: il buffer è pieno

L'expéditeur bloque uniquement lorsque le tampon est plein ; le récepteur seul quand il est vide.

proche et à distance

L'expéditeur ferme le canal lorsqu'il n'y a plus de valeurs :

Go
ch := make(chan int, 3)
ch <- 1
ch <- 2
ch <- 3
close(ch)

for v := range ch {      // termina quando ch è chiuso E vuoto
    fmt.Println(v)
}

for range sur un canal itère jusqu'à ce que le canal soit fermé (et vidé). C'est le modèle le plus propre : « consommer tout ce qui vient ».

Directionnalité dans les signatures

Les paramètres de fonction peuvent limiter la direction :

Go
func producer(out chan<- int) {   // solo invio
    out <- 1
    close(out)
}

func consumer(in <-chan int) {    // solo ricezione
    for v := range in {
        fmt.Println(v)
    }
}

chan<- T = envoi uniquement, <-chan T = réception uniquement. Le canal "bidirectionnel" chan T peut être transmis aux deux (conversion implicite). Augmentation clarté et évite les erreurs.

Modèles courants (aperçu)

  • Groupe de travailleurs : N goroutines consomment à partir de jobs <-chan T, produisent sur results chan<- R.
  • Pipeline : étapes connectées par canal.
  • Signal terminé : canal chan struct{} fermé pour signaler "stop".
Go
done := make(chan struct{})
go func() {
    <-done    // blocca finché qualcuno chiude done
    cleanup()
}()
close(done)   // segnale di stop

chan struct{} est le canal « signal » : aucun octet de charge utile, uniquement synchronisation.

Essayez-le vous-même

Exercice#go.m7.l2.e1
Tentatives : 0Chargement…

Créez un canal ch d'int sans tampon, envoyez 42 depuis une goroutine, recevez en main et imprimez.

Chargement de l'éditeur…
Afficher l'indice

Sans mise en mémoire tampon, l'expéditeur et le destinataire se synchronisent.

Solution disponible après 3 tentatives

Exercice#go.m7.l2.e2
Tentatives : 0Chargement…

Envoyez 1,2,3 sur un canal tamponné, fermez-le, puis imprimez le tout avec for-range.

Chargement de l'éditeur…
Afficher l'indice

`for range` sur un canal se termine lorsque le canal est fermé et vidé.

Solution disponible après 3 tentatives

Quiz#go.m7.l2.e3
Prêt

Que fait un canal UNBUFFERED lorsque l'expéditeur envoie mais qu'aucun récepteur n'est prêt ?

Go
ch := make(chan int)
ch <- 1 // ?
Options de réponse

Récapitulatif

  • Channel = file d'attente typée FIFO, sécurisée entre les goroutines.
  • Unbuffered : rendez-vous (synchronisation de l'expéditeur et du destinataire).
  • Buffered : découplage, blocage uniquement lorsqu'il est plein/vide.
  • close(ch) : uniquement l'expéditeur ; for range consomme jusqu'à la fermeture.
  • Directionnalité : chan<- T (envoi uniquement), <-chan T (réception uniquement).
  • chan struct{} comme canal de signal pour une synchronisation pure.