Pourquoi recevoir des valeurs d'un canal fermé est possible
Dans Go, les canaux fournissent un mécanisme de communication entre les goroutines. Lorsqu'un canal est fermé, cela indique qu'aucune autre valeur ne sera envoyée. Cependant, cela ne signifie pas que les valeurs existantes dans le tampon du canal sont immédiatement supprimées.
La spécification indique qu'après la fermeture d'un canal, toutes les valeurs précédemment envoyées peuvent toujours être reçues avant de recevoir la valeur zéro. En effet, le tampon du canal agit comme une file d'attente, stockant les valeurs envoyées avant l'opération de fermeture.
Comment ça marche :
Considérez le code suivant :
package main import "fmt" import "sync" import "time" func main() { iCh := make(chan int, 99) var wg sync.WaitGroup go func() { for i := 0; i < 5; i++ { wg.Add(1) go func(i int) { defer wg.Done() iCh <- i }(i) } wg.Wait() close(iCh) }() time.Sleep(5 * time.Second) for i := range iCh { fmt.Printf("%v\n", i) } }
Sortie :
0 1 2 3 4
Même si le canal est fermé après 5 secondes, la boucle for reçoit toujours les 5 valeurs qui ont été envoyées avant l'opération de fermeture. En effet, le tampon du canal stocke ces valeurs jusqu'à ce qu'elles soient consommées.
Ce n'est qu'après avoir reçu toutes les valeurs précédemment envoyées que la boucle for renvoie la valeur zéro, indiquant que le canal est fermé.
Pourquoi l'astuce "Time.Sleep" échoue :
L'astuce "time.Sleep" n'empêche pas les goroutines de continuer à envoyer des valeurs dans le canal avant sa fermeture. Pendant que les goroutines dorment pendant 5 secondes, elles pourraient envoyer des valeurs supplémentaires qui seraient toujours mises en mémoire tampon et reçues par la boucle for.
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!