Programmation asynchrone en Go : guide complet pour débutants

Formateur Python en ligne pour débutants

Apprenez Python facilement sans surcharge théorique. Résolvez des tâches pratiques avec vérification automatique et écrivez du code directement dans le navigateur.

Start Course

Programmation asynchrone en Go : guide complet pour débutants

\n\n

La programmation asynchrone est une approche dans laquelle un programme peut exécuter plusieurs tâches simultanément sans bloquer l'exécution du thread principal. En langage Go (Golang), ce mécanisme est implémenté de manière particulièrement élégante et simple grâce aux primitives intégrées : les goroutines et les canaux (channels). Contrairement à de nombreux autres langages où l'asynchronisme nécessite des callbacks complexes ou des promesses, Go offre une syntaxe concise et des outils puissants pour travailler avec la concurrence.

\n\n

Dans ce guide, nous allons aborder les bases de la programmation asynchrone en Go. Vous apprendrez ce que sont les goroutines, comment les créer et les synchroniser à l'aide de canaux, ainsi que comment utiliser l'opérateur select pour travailler avec plusieurs canaux. Le contenu est conçu pour les débutants, donc tous les exemples seront aussi simples et clairs que possible.

\n\n

Que sont les goroutines et comment fonctionnent-elles

\n\n

Une goroutine est un fil d'exécution léger géré par le runtime de Go. Contrairement aux threads classiques du système d'exploitation, les goroutines consomment beaucoup moins de ressources : la pile d'une goroutine commence à quelques kilo-octets et peut s'étendre dynamiquement. Lancer une goroutine se fait simplement en ajoutant le mot-clé go avant un appel de fonction :

\n\n
package main\n\nimport (\n    "fmt"\n    "time"\n)\n\nfunc printMessage(msg string) {\n    for i := 0; i < 3; i++ {\n        fmt.Println(msg)\n        time.Sleep(100 * time.Millisecond)\n    }\n}\n\nfunc main() {\n    // Lancement d'une goroutine\n    go printMessage("Bonjour depuis la goroutine !")\n    \n    // Fonction principale\n    printMessage("Bonjour depuis main !")\n    \n    // Attente de la fin de la goroutine\n    time.Sleep(1 * time.Second)\n}
\n\n

Dans cet exemple, la fonction printMessage est lancée deux fois : une fois comme fonction normale, une fois comme goroutine. L'exécution se fait de manière concurrente : les messages seront mélangés. Notez que sans time.Sleep à la fin de main, le programme se terminerait sans attendre l'exécution de la goroutine. Pour une synchronisation fiable, il est préférable d'utiliser des mécanismes spécialisés.

\n\n

Canaux : transfert sécurisé de données entre goroutines

\n\n

Les canaux (channels) sont des "tuyaux" typés par lesquels les goroutines peuvent échanger des données. Un canal est créé à l'aide de la fonction make et de l'opérateur chan. Les données sont envoyées dans le canal via <-, et reçues avec une syntaxe similaire.

\n\n

Considérons un exemple de base :

\n\n
package main\n\nimport "fmt"\n\nfunc sendData(ch chan string) {\n    ch <- "Données depuis la goroutine"\n}\n\nfunc main() {\n    // Création d'un canal pour les chaînes\n    messageChannel := make(chan string)\n    \n    // Lancement d'une goroutine qui envoie des données\n    go sendData(messageChannel)\n    \n    // Réception des données du canal (bloquant jusqu'à réception)\n    message := <-messageChannel\n    \n    fmt.Println(message)\n}
\n\n

Ici, la goroutine envoie une chaîne dans le canal, et main attend de la recevoir. Important : les opérations sur les canaux sont par défaut bloquantes. L'envoi dans un canal est bloqué jusqu'à ce que les données soient reçues, et vice versa. Cela assure une synchronisation naturelle.

\n\n

Les canaux peuvent être tamponnés. Le tampon permet d'envoyer des données sans blocage, jusqu'à ce que le tampon soit plein :

\n\n
// Création d'un canal tamponné de 2 éléments\nbufferedChannel := make(chan string, 2)\n\n// Envoi de données sans blocage\nbufferedChannel <- "Premier"\nbufferedChannel <- "Deuxième"\n\n// On peut maintenant recevoir les données\nfmt.Println(<-bufferedChannel)\nfmt.Println(<-bufferedChannel)
\n\n

Opérateur select : travailler avec plusieurs canaux

\n\n

Lorsque vous avez plusieurs canaux et que vous souhaitez réagir à celui qui

Blogs

Book Recommendations