Aller au contenu

Patterns de concurrence et select#

Introduction au select#

  • Le mot-clé select est un mécanisme fondamental en Go pour gérer plusieurs communications simultanément.
  • select permet de surveiller plusieurs canaux en même temps, et de bloquer jusqu'à ce qu'un de ces canaux soit prêt pour effectuer une opération d'envoi ou de réception.
  • La syntaxe de base de select est similaire à celle d'un switch mais pour les canaux.

Exemple de code :

select {
case <-canal1:
    // Traiter le cas du canal 1
case canal2 <- valeur:
    // Envoyer une valeur sur le canal 2
default:
    // Cas par défaut si aucun autre cas n'est prêt
}

Introduction au pattern "fan-in/fan-out"#

  • Le pattern "fan-in/fan-out" est un modèle de conception couramment utilisé pour la gestion de la concurrence en Go.
  • "Fan-out" signifie démarrer plusieurs goroutines pour gérer des tâches en parallèle et "fan-in" signifie combiner plusieurs résultats en un seul.
  • Ces modèles peuvent être combinés avec select pour gérer efficacement les tâches parallèles.

Exemple de code :

func fanIn(input1, input2 <-chan string) <-chan string {
    output := make(chan string)
    go func() {
        for {
            select {
            case s := <-input1:
                output <- s
            case s := <-input2:
                output <- s
            }
        }
    }()
    return output
}

Utilisation de select pour gérer plusieurs canaux#

  • select est l'outil parfait pour gérer plusieurs communications sur différents canaux.
  • Il peut gérer aussi bien les cas d'envoi que de réception sur plusieurs canaux, et bloquera jusqu'à ce qu'un des canaux soit prêt.

Exemple de code :

select {
case msg1 := <-c1:
    fmt.Println("received", msg1)
case msg2 := <-c2:
    fmt.Println("received", msg2)
}

Timeouts et tickers avec select#

  • Les timeouts et les tickers sont des fonctionnalités importantes pour gérer le temps en Go.
  • Le package time en Go fournit des tickers pour effectuer des actions à intervalles réguliers et des timeouts pour limiter le temps d'attente d'une opération.

Exemple de code :

select {
case <-time.After(1 * time.Second):
    fmt.Println("timeout 1 second")
case res := <-result:
    fmt.Println("received", res)
}

Implémentation de patterns de concurrence avancés#

  • Au-delà du "fan-in/fan-out", il existe de nombreux patterns avancés en Go pour gérer des scénarios de concurrence plus complexes, comme le pipeline, le pool de workers, etc.
  • Il est recommandé d'explorer ces patterns dans la documentation officielle de Go et dans des ressources telles que le livre "Concurrency in Go" de Katherine Cox-Buday.

Bonnes pratiques pour la programmation concurrente en Go#

  • Toujours fermer les canaux lorsqu'ils ne sont plus utilisés.
  • Utiliser select avec un default case pour éviter les blocages inutiles.
  • Préférer l'utilisation de canaux pour la communication entre goroutines plutôt que le partage de mé

moire. * Utiliser sync package pour les primitives de synchronisation de bas niveau comme les Mutex ou les WaitGroups. * Eviter les race conditions en utilisant les outils fournis par Go tels que le race detector (go run -race your_go_file.go).