Contactez-nous

Introduction à la concurrence Go

Découvrez les bases de la concurrence en Go. Apprenez à lancer des goroutines pour l'exécution parallèle et à utiliser les canaux (channels) pour la communication et la synchronisation.

La force tranquille de Go : Aborder la concurrence

L'un des atouts majeurs et des caractéristiques les plus distinctives du langage Go est son approche intégrée et simplifiée de la concurrence. La concurrence est la capacité d'un système à exécuter plusieurs tâches ou processus de manière indépendante, semblant souvent se dérouler en même temps. Dans le monde moderne du développement logiciel, où les applications doivent être réactives, traiter de grands volumes de données ou interagir avec de multiples services externes, la maîtrise de la concurrence est devenue essentielle.

Go a été conçu dès le départ pour faciliter l'écriture de programmes concurrents corrects et efficaces. Plutôt que de s'appuyer sur des mécanismes complexes de threads et de verrous souvent sources d'erreurs, Go propose des primitives de haut niveau intégrées au langage lui-même.

Ce chapitre est votre porte d'entrée dans le monde fascinant de la concurrence en Go. Nous allons explorer les deux piliers de ce modèle : les goroutines pour lancer des tâches concurrentes et les canaux (channels) pour orchestrer leur communication et leur synchronisation.

Lancer des tâches en parallèle : Les Goroutines

Au coeur de la concurrence en Go se trouvent les goroutines. Une goroutine peut être vue comme une fonction qui s'exécute indépendamment, en parallèle avec les autres goroutines (y compris la goroutine principale qui exécute la fonction `main`). La création et la gestion des goroutines sont extrêmement légères comparées aux threads systèmes traditionnels, permettant d'en lancer des milliers, voire des millions, sans impacter lourdement les ressources système.

Nous verrons comment lancer une goroutine est d'une simplicité déconcertante : il suffit de préfixer un appel de fonction (ou de méthode) par le mot-clé `go`. La fonction s'exécutera alors de manière asynchrone, sans bloquer l'exécution du code appelant.

Communiquer et synchroniser : Les Canaux (Channels)

Lancer des tâches en parallèle est une chose, mais comment faire pour qu'elles communiquent entre elles ou se coordonnent ? Go encourage fortement la communication via les canaux (channels) plutôt que le partage direct de mémoire (bien que ce dernier soit possible via le paquet `sync`).

Un canal est un conduit typé à travers lequel on peut envoyer et recevoir des valeurs entre goroutines, assurant ainsi une communication sûre et synchronisée. Nous apprendrons à créer des canaux avec `make`, à envoyer des données dans un canal en utilisant l'opérateur `<-` (`canal <- valeur`), et à recevoir des données depuis un canal (`valeur <- canal`). Nous verrons aussi comment fermer un canal (`close(canal)`) pour signaler qu'aucune autre valeur ne sera envoyée.

L'utilisation des canaux est fondamentale pour l'orchestration des goroutines et constitue l'approche idiomatique pour construire des systèmes concurrents en Go.

Orchestration de base : Attente et Itération sur les Canaux

Lorsque l'on lance plusieurs goroutines, il est souvent nécessaire d'attendre qu'elles aient toutes terminé leur travail avant de continuer ou de terminer le programme principal. Pour cette synchronisation simple, nous introduirons le type `sync.WaitGroup` qui permet de gérer un compteur de goroutines actives et d'attendre que ce compteur retombe à zéro.

Enfin, nous verrons comment la boucle `for range`, que nous connaissons déjà pour les slices et les maps, peut être utilisée de manière très élégante pour recevoir des valeurs d'un canal de manière répétée, jusqu'à ce que ce canal soit fermé. C'est une manière concise et claire de traiter un flux de données provenant d'une autre goroutine.

Ce chapitre vous fournira les bases essentielles pour commencer à exploiter la puissance de la concurrence en Go, en utilisant ses primitives clés de manière simple et idiomatique.