Go: Channels et Goroutines

Je me suis lancé dans l’apprentissage du langage Go. Lorsque Go a été lancé publiquement en 2009 je m’y étais intéressé que de loin, à mon regret. Car finalement ce langage est bien intéressant et présente certains avantages, particulièrement concernant la programmation concurrente. Ce qui peut résoudre des problèmes de programmation réseau. Pour le moment les aspects qui me plaisent le plus sont donc les channels et les goroutines.

Voici une illustration avec le problème du producteur/consommateur:

package main

import ("fmt")

var done = make(chan bool)
var cake = make(chan int)

func produce (firstname string) {
    for i := 0; i < 10; i++ {
        fmt.Printf("%s make cake %d\n", firstname, i)
        cake <- i
    }
    done <- true
}

func consume (firstname string) {
    for {
      cake_number := <-cake
      fmt.Printf("%s eat cake %d\n", firstname, cake_number)
   }
}

func main () {
   go produce("Alice")
   go consume("Bob")
   go consume("Maxime")
   <- done
} 

Aux lignes 24, 25 et 26 nous lançons 3 goroutines. Il s'agit en fait de 3 threads. Alice va faire des gâteaux pendant que Bob et Maxime vont les manger.

À la ligne 6 nous définissons un channel nommé cake. On peut voir un channel comme un tube FIFO (First In, First Out). Tant que l'envoie de données (cake <- i) dans le tube n'est pas terminé, il n'est pas possible de recevoir des données (cake_number := <-cake) de l'autre côté. Ce qui permet de synchroniser des goroutines sans utiliser de mutex ou autres verrous.

Voici donc le résultat de l'exécution de ce petit programme:

cedric@kubuntu:~$ 6g produc-consum.go
cedric@kubuntu:~$ 6l -o produc-consum produc-consum.6
cedric@kubuntu:~$ ./produc-consum 
Alice make cake 0
Alice make cake 1
Bob eat cake 0
Alice make cake 2
Maxime eat cake 1
Alice make cake 3
Bob eat cake 2
Alice make cake 4
Maxime eat cake 3
Maxime eat cake 4
Alice make cake 5
Alice make cake 6
Bob eat cake 5
Alice make cake 7
Maxime eat cake 6
Alice make cake 8
Bob eat cake 7
Alice make cake 9
Maxime eat cake 8
Bob eat cake 9

Personnellement j'aime assez l'idée des channels. Voici un autre exemple intéressant.

4 comments

  1. Je ne suis pas spécialiste, mais ça ressemble à des structures de données (ici FIFO) «thread safe». Autrement dit, le mécanisme de verrous est bien présent, mais déplacé aux primitives de la structure de données.

    Quand tu auras fini d’apprendre Go, tu pourras apprendre Haskell: http://tryhaskell.org

    1. Moi non plus je ne suis pas spécialiste et je pense en effet qu’il s’agit d’une structure thread safe. Je pense que les mécanismes de verrous sont quand même bien gérés en interne, c’est quand même un des objectifs principal du langage. Ken Thompson a du vouloir améliorer certains défauts du C, inhérents à son époque peut être. Aujourd’hui on utilise plus en plus de programmation concurrente, sans parler du réseau (sauf peut être les puristes qui font du fonctionnel 😉 ).
      Bref, si j’apprends comment fonctionne un channel je penserai à le noter ici!

      Haskell aussi j’aimerai bien apprendre. Ça à l’ai bien sympa et je ne connaissais pas ton lien. Faudrait que je regarde et que je le compare à Objective Caml (le seul langage vraiment fonctionnel que je connaisse) juste pour moi.

      Tu programmes en Haskell? De manière général tu utilises souvent des langages comme Objective Caml pour du réseau, parser des fichiers, des maths (crypto, etc.)… ? Ou dans un but “plus théorique”?

      C’est chiant, y a bien trop de langages intéressants. Je me demande toujours comment on fait pour faire tant de Java.

      1. Malheureusement je ne connais pas encore bien Haskell, je comptais sur toi pour faire un billet intéressant dessus 😉

        J’utilise python/bash pour faire des scripts rapides et utiles à moi-même, ocaml pour faire des traitements plus complexes, Coq pour faire des preuves formelles, LaTeX pour le texte … et C/Java pour l’enseignement.
        Mais en fait, en ce moment, je ne développe pas d’application complète.

        Encore peu répandus chez les développeurs, il y a des langages à types dépendants dont j’ai déjà dû parler sur ce blog: par ex. epigram, agda.

        1. Ces langages semblent intéressants, je regarderai lorsque j’aurai un peu le temps, si je trouve quelque part une petite introduction à l’un des deux. epigram à l’air d’utiliser des composants de Haskell.

Comments are closed.