Wie zu warten, bis gepufferten Kanal (semaphore) leer ist?
Habe ich eine Scheibe von ganzen zahlen, die manipuliert werden, die gleichzeitig:
ints := []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
Ich bin mit einer gepufferten Kanal als semaphore, um eine Obere Grenze der gleichzeitig ausgeführten go-Routinen:
sem := make(chan struct{}, 2)
for _, i := range ints {
//acquire semaphore
sem <- struct{}{}
//start long running go routine
go func(id int, sem chan struct{}) {
//do something
//release semaphore
<- sem
}(i, sem)
}
Den code oben funktioniert ziemlich gut, bis der Letzte oder die letzten zwei ganze zahlen werden erreicht, weil das Programm endet, bevor die letzten gehen-Routinen sind abgeschlossen.
Frage: wie ich warten Sie für den gepufferten Kanal ablassen?
- Du musst einen mutex verwenden oder so etwas. Die gepufferten Kanal blockiert, wenn er voll ist, aber es gibt keine Sprache-Funktion zu blockieren, bis es leer ist.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Können Sie nicht verwenden, eine semaphor-Kanal (in diesem Fall) auf diese Weise. Es gibt keine Garantie, es wird nicht leer beliebigen Punkt während der Verarbeitung der Werte und der Versand mehr goroutines. Das ist kein Problem, in diesem Fall speziell, da du dich dispatching arbeiten synchron, aber da gibt ' s kein Rennen-freie Möglichkeit zu prüfen, einen Kanal die Länge, es gibt keine primitiven warten, bis der Kanal die Länge auf den Wert 0 erreichen.
Verwenden
sync.WaitGroup
zu warten, bis alle goroutines abgeschlossenWaitGroup
. Dies fühlt sich wie der richtige Weg!Verwenden Sie "worker-pool" verarbeiten Sie Daten. Es ist cheeper als laufen Sie goroutine für jeder int, Speicher, Variablen und so weiter...
Klar, es ist niemand wartet auf Ihr go-Routinen zu vervollständigen. So ist das Programm beendet, bevor die letzten 2 go-Routinen sind abgeschlossen. Sie können eine Arbeitsgruppe zu warten, bis alle Ihre go-Routinen abgeschlossen ist, bevor das Programm endet. Das sagt er besser https://nathanleclaire.com/blog/2014/02/15/how-to-wait-for-all-goroutines-to-finish-executing-before-continuing/
WorkGroup
funktioniert perfekt. JimB Antworten diese geklärt