Menu
Coddy logo textTech

Canaux et communication

Fait partie de la section Programmation Orientée Objet du Journey GO de Coddy. Leçon 60 sur 107.

Les canaux sont le principal mécanisme de Go pour la communication entre les goroutines. Plutôt que de partager directement la mémoire, les goroutines envoient et reçoivent des valeurs par l’intermédiaire des canaux, conformément à la philosophie de Go : « Ne communiquez pas en partageant la mémoire ; partagez la mémoire en communiquant. »

Créez un canal à l’aide de la fonction make avec le mot-clé chan :

messages := make(chan string)

Utilisez l'opérateur flèche <- pour envoyer et recevoir des valeurs. La flèche indique la direction du flux de données :

func main() {
    messages := make(chan string)
    
    go func() {
        messages <- "hello"  // envoyer au canal
    }()
    
    msg := <-messages  // recevoir du canal
    fmt.Println(msg)   // Sortie : hello
}

Par défaut, les envois et les réceptions sont bloquants jusqu’à ce que l’autre partie soit prête. Lorsque la goroutine envoie "hello", elle attend que main soit prête à recevoir. Ce comportement bloquant fournit une synchronisation intégrée : aucun time.Sleep n’est nécessaire.

Vous pouvez fermer un canal pour signaler qu’aucune autre valeur ne sera envoyée. Les récepteurs peuvent le détecter :

close(messages)

msg, ok := <-messages
if !ok {
    fmt.Println("Channel closed")
}

Les canaux sont typés : un chan string ne peut transporter que des chaînes. Cette sécurité de typage garantit que les goroutines communiquent avec les types de données appropriés, en détectant les erreurs au moment de la compilation plutôt qu’à l’exécution.

challenge icon

Défi

Facile

Construisons un système de relais de messages qui montre comment les goroutines communiquent via des canaux. Vous allez créer un pipeline dans lequel les messages circulent entre différentes étapes de traitement, chaque étape s’exécutant simultanément.

Vous organiserez votre code sur deux fichiers :

  • relay.go : Définissez votre pipeline de traitement des messages.

    Créez une structure Message avec les champs ID (int) et Content (string).

    Implémentez trois fonctions qui représentent différentes étapes de votre pipeline :

    • Producer(messages []Message, out chan Message) - Reçoit une tranche de messages et envoie chacun d’eux au canal de sortie. Après avoir envoyé tous les messages, fermez le canal pour signaler la fin du traitement.
    • Transformer(in chan Message, out chan Message) - Reçoit les messages du canal d’entrée, transforme le contenu de chaque message en majuscules, puis envoie le message transformé au canal de sortie. Lorsque le canal d’entrée est fermé (ce qui est détecté à l’aide de la forme de réception à deux valeurs), fermez le canal de sortie.
    • Consumer(in chan Message) []string - Reçoit tous les messages du canal d’entrée et les rassemble dans une tranche de chaînes formatées. Chaque chaîne doit respecter le format : Message [ID]: [Content]. Retournez la tranche lorsque le canal est fermé.
  • main.go : Configurez le pipeline et orchestrez le flux de messages simultané.

    Lisez le nombre de messages, puis lisez l’identifiant et le contenu de chaque message. Créez les messages et configurez deux canaux pour relier les trois étapes du pipeline. Lancez Producer et Transformer en tant que goroutines, puis exécutez Consumer dans la goroutine principale afin de recueillir les résultats. Affichez chaque résultat sur une ligne distincte.

Les entrées suivantes seront fournies :

  • Ligne 1 : nombre de messages (entier)
  • Lignes suivantes : pour chaque message, deux lignes : l’identifiant du message (entier), puis son contenu (chaîne)

Par exemple, avec :

2
1
hello world
2
go channels

Votre sortie doit être :

Message 1: HELLO WORLD
Message 2: GO CHANNELS

Le pipeline fonctionne ainsi : Producer envoie les messages → Transformer les convertit en majuscules → Consumer rassemble et formate les résultats. Chaque flèche représente un canal reliant des étapes simultanées. Utilisez le package strings pour la transformation en majuscules.

Essayez vous-même

package main

import (
	"bufio"
	"fmt"
	"os"
	"strconv"
	"strings"
)

func main() {
	reader := bufio.NewReader(os.Stdin)

	// Lire le nombre de messages
	nLine, _ := reader.ReadString('\n')
	n, _ := strconv.Atoi(strings.TrimSpace(nLine))

	// Lire les messages
	messages := make([]Message, n)
	for i := 0; i < n; i++ {
		idLine, _ := reader.ReadString('\n')
		id, _ := strconv.Atoi(strings.TrimSpace(idLine))
		contentLine, _ := reader.ReadString('\n')
		content := strings.TrimSpace(contentLine)
		messages[i] = Message{ID: id, Content: content}
	}

	// TODO: Créer deux canaux pour connecter les étapes du pipeline

	// TODO: Lancer Producer en tant que goroutine

	// TODO: Lancer Transformer en tant que goroutine

	// TODO: Exécuter Consumer dans la goroutine principale et collecter les résultats

	// TODO: Afficher chaque résultat sur une ligne séparée
}
quiz iconTestez-vous

Cette leçon comprend un petit quiz. Commencez la leçon pour y répondre et suivre votre progression.

Toutes les leçons de Programmation Orientée Objet

Entraînez-vous par vous-même : Compilateur Go en ligne