Section 2 : Goroutines
Les goroutines sont une des caractéristiques du langage Go, qui facilitent la programmation concurrente. Une goroutine est une sorte de thread léger, mais géré par le runtime de Go et non par le système d'exploitation. Vous pouvez démarrer une goroutine simplement en utilisant le mot clé go devant un appel de fonction.
Exemple : avec time.Sleep
Voici un exemple simple qui illustre l'utilisation de goroutines :
Dans cet exemple, countdown est une fonction qui affiche le décompte de n à 0. En préfixant l'appel de fonction countdown(5, i) par le mot clé go dans la boucle de la fonction main, Go créera une nouvelle goroutine pour chaque appel de fonction et commencera son exécution de manière concurrente.
Le time.Sleep à la fin de la fonction main est nécessaire pour empêcher que le programme principal ne se termine avant que les goroutines aient fini leur décompte. En vrai code, vous devriez utiliser des mécanismes de synchronisation comme des groupes d'attentes (WaitGroups) ou des canaux (channels) pour contrôler l'exécution de vos goroutines, mais pour un exemple simple comme celui-ci, un simple time.Sleep suffit pour illustrer le principe.
À noter que l'ordre d'exécution précis des goroutines n'est pas garanti et peut varier à chaque exécution. C'est l'un des défis de la programmation concurrente : la nécessité de bien synchroniser les différentes tâches pour éviter des conflits ou des comportements imprévisibles.
Exemple : avec canal
Dans cet exemple, nous avons modifié la déclaration du canal done pour qu'il soit un canal de bool. Nous avons aussi ajouté une capacité à la création du canal pour éviter un blocage si les goroutines finissent leur décompte avant que main commence à recevoir sur le canal. Ensuite, nous envoyons true sur le canal done dans chaque goroutine après qu'elle a fini son décompte. Enfin, à la fin de main, nous recevons de chaque goroutine sur le canal done pour attendre qu'elle ait fini.
Exemple avec WaitGroup
Le package sync de Go fournit une structure WaitGroup qui peut être utilisée pour synchroniser plusieurs goroutines. Voici comment on pourrait modifier notre exemple pour utiliser un WaitGroup:
La méthode Add est utilisée pour augmenter le compteur du WaitGroup. Chaque fois que nous lançons une goroutine, nous augmentons le compteur de 1. La méthode Done est appelée pour diminuer le compteur lorsque la goroutine a fini son travail. Enfin, la méthode Wait est utilisée pour bloquer la goroutine actuelle (dans ce cas, la goroutine principale) jusqu'à ce que le compteur du WaitGroup atteigne zéro, c'est-à-dire que toutes les goroutines qu'il attend ont signalé qu'elles sont terminées. Cela nous permet d'attendre de manière sûre et flexible l'achèvement de toutes les goroutines.