Canaux et communication entre goroutines#
Introduction aux canaux (channels)#
- Les canaux (channels) sont des conduits utilisés pour le transfert de données entre différentes goroutines. Ils sont un élément central de la programmation concurrente avec Go.
- Pour consulter la documentation officielle sur les canaux, se référer à la documentation officielle Go.
Création et utilisation des canaux#
- Pour créer un canal, on utilise la commande
make
. Par exemple :ch := make(chan int)
. - Pour envoyer des données à travers un canal, on utilise l'opérateur
<-
. Par exemple :ch <- 5
. - Pour recevoir des données d'un canal, on utilise aussi l'opérateur
<-
. Par exemple :val := <-ch
.
Types de canaux: non-buffered, buffered, unidirectionnels et bidirectionnels#
- Les canaux non-buffered (ou synchrones) sont des canaux où l'envoi et la réception de données sont bloquants. C'est-à-dire qu'une goroutine qui envoie des données à un canal non-buffered se bloque jusqu'à ce qu'une autre goroutine reçoive ces données. Ils sont créés avec
ch := make(chan int)
. - Les canaux buffered (ou asynchrones) sont des canaux où l'envoi et la réception de données ne sont pas bloquants. Une goroutine peut envoyer des données à un canal buffered sans se bloquer, à condition que le canal ait suffisamment de place pour stocker ces données. Ils sont créés avec
ch := make(chan int, 3)
où 3 est la taille du buffer. - Les canaux unidirectionnels sont des canaux qui peuvent soit uniquement envoyer des données (
chan<- int
), soit uniquement recevoir des données (<-chan int
). - Les canaux bidirectionnels peuvent envoyer et recevoir des données. C'est le type par défaut des canaux (
chan int
).
Communication entre goroutines via les canaux#
- Les canaux permettent de synchroniser et de communiquer entre les goroutines.
- Par exemple, pour attendre qu'une goroutine finisse son travail avant de continuer, on peut utiliser un canal. Une fois que la goroutine a terminé son travail, elle envoie une valeur à travers le canal, ce qui débloque la goroutine qui attendait.
Canaux unidirectionnels et bidirectionnels#
- Les canaux unidirectionnels sont utiles pour exprimer clairement l'intention du programme. Par exemple, si une fonction reçoit un
chan<- int
, on sait qu'elle ne fera qu'envoyer des données à ce canal. - Les canaux bidirectionnels sont plus flexibles mais peuvent rendre le code plus difficile à comprendre.
- Il est important de noter que les canaux unidirectionnels et bidirectionnels ne sont pas compatibles. On ne peut pas passer un
chan int
à une fonction qui attend unchan<- int
ou un<-chan int
.
Gestion des canaux avec close et range#
- Pour fermer un canal, on utilise la fonction
close
. Par exemple :close(ch)
. - Lorsqu'un canal est fermé, on ne peut plus y envoyer de données, mais on peut toujours en recevoir.
- Pour parcourir toutes les valeurs d'un canal jusqu'à ce qu'il soit fermé, on utilise
une boucle for
avec range
. Par exemple : for val := range ch
.
* Il est recommandé de toujours fermer les canaux pour éviter les fuites de mémoire.