J'échangeais simplement des chaînes Go sur mon environnement Ubuntu 64 bits et que vous avez confondu avec la sortie le programme suivant produit.
J'ai reçu la sortie: 0 1 2 3 Quittez p>
la sortie lorsque je déconnecte les deux lignes commentées: 0 1 2 3 4 Quittez P>
S'il vous plaît expliquer le comportement. TIA. P>
package main
import (
"fmt"
//"time"
)
func main() {
ch := make(chan int)
done := make(chan bool)
go func() {
for i := 0; i < 5; i++ {
ch <- i
}
//time.Sleep(1 * time.Second)
done <- false
}()
go func() {
for {
select {
case message := <-ch:
fmt.Println(message)
case <-done:
return
}
}
}()
<-done
fmt.Println("Exit")
}
3 Réponses :
Votre thread principal attend sur La valeur dans Notez que si votre deuxième thread avait em> est arrivé à la fois de effectué code>, puis sortant. Pendant ce temps, vos premiers tuyaux fonctionnent 5 valeurs dans ch code>, puis envoie à effectué code>. P>
effectuée code> est ensuite lue à partir du thread principal et arrive em> se produire avant la deuxième fonction GO lit la dernière valeur de ch code> . Quand cela le fait, il quitte le programme. P>
ch code> et effectué code>, alors votre programme serait une impasse car le fil principal serait Ne jamais recevoir sur effectué code> et tous les threads en cours d'exécution seront bloqués en attente de recevoir sur des canaux. P>
Vous avez deux Notez qu'une fois la routine GO responsable de l'enquentaser les chiffres dans les finitions de canal, il signale le fil principal à quitter, que la routine GO litture des chiffres est terminé ou non. Donc, vous pourriez vous retrouver avec un cas où la routine d'Enqueuseing est terminée avant la finition du déséquilibre et que le fil principal est sorti. P>
En ajoutant le sommeil, vous rendez la routine en courseuse en train de vivre un peu plus longtemps et donnez une chance à la routine de déroeue pour lire et imprimer tous les numéros avant que la routine d'Enqueue, le fil principal pour quitter. P>
Pour résoudre cela, vous pouvez simplement exécuter le code de déséquilibre dans le fil principal. Pas besoin de l'exécuter dans une routine Go dans ce cas. P> go code> routines fonctionnant en parallèle. On insère 5 nombres dans le canal, puis signale le fil principal à quitter et un autre lit les chiffres du canal. P>
Vous n'attendez pas les deux goroutines et n'envoie que la valeur unique sur Utilisation d'un effectué code> sur 2 récepteurs, qui va une impasse si le deuxième récepteur se trouve être principal code>. WaitGroup code> simplifie le code et vous permet d'attendre facilement autant de gorouts que nécessaire. https://play.golang.org/p/mwknv_9afkp P> ch := make(chan int)
var wg sync.WaitGroup
wg.Add(1)
go func() {
defer wg.Done()
defer close(ch)
for i := 0; i < 5; i++ {
ch <- i
}
}()
wg.Add(1)
go func() {
defer wg.Done()
for message := range ch {
fmt.Println(message)
}
}()
wg.Wait()
fmt.Println("Exit")
Il n'y a pas de numéros de ligne ci-dessus ;-) Mieux vaut vouloir dire qu'ils sont déjà moralisés.