Wie man einen mit mehreren Goroutinen gefüllten Kanal schließt, wenn alle Arbeiten abgeschlossen sind, ist eine häufig gestellte Frage. In Go ist das Schließen eines Kanals eine Möglichkeit, dem Empfänger mitzuteilen, dass keine Daten mehr vorhanden sind. Durch das Schließen des Kanals kann der Empfänger rechtzeitig erkennen, dass der Sender alle Sendevorgänge abgeschlossen hat. In einem Kanal mit mehreren Goroutinen können wir einen Zähler verwenden, um zu verfolgen, wie viele weitere Goroutinen Daten an den Kanal senden. Wenn der Zähler auf 0 fällt, sind alle Arbeiten abgeschlossen und wir können den Kanal sicher schließen. Nach dem Schließen des Kanals kann der Empfänger mithilfe zusätzlicher Variablen im Empfangsausdruck feststellen, ob der Kanal geschlossen wurde. Auf diese Weise können wir sicherstellen, dass von mehreren Goroutinen gefüllte Kanäle nach Abschluss aller Arbeiten ordnungsgemäß geschlossen werden, wodurch Ressourcenlecks und Deadlock-Probleme vermieden werden.
Ich versuche, dem Go-Weg zu folgen, „nicht über den gemeinsamen Speicher zu kommunizieren, sondern den Speicher durch Kommunikation zu teilen“ und Kanäle zu verwenden, um zu erledigende Aufgaben asynchron zu kommunizieren und die Ergebnisse der Verarbeitungsaufgaben zurückzusenden.
Der Einfachheit halber habe ich die Kanaltypen in int anstelle ihrer tatsächlichen Strukturen geändert. Und lange Bearbeitung durch time.Sleep()
ersetzt.
Wie schließe ich ProducedResults
,以便此代码不会卡在最后一个 for
, nachdem alle Aufgabenergebnisse zurückgesendet wurden?
quantityOfTasks:= 100 quantityOfWorkers:= 60 remainingTasks := make(chan int) producedResults := make(chan int) // produce tasks go func() { for i := 0; i < quantityOfTasks; i++ { remainingTasks <- 1 } close(remainingTasks) }() // produce workers for i := 0; i < quantityOfWorkers; i++ { go func() { for taskSize := range remainingTasks { // simulate a long task time.Sleep(time.Second * time.Duration(taskSize)) // return the result of the long task producedResults <- taskSize } }() } // read the results of the tasks and agregate them executedTasks := 0 for resultOfTheTask := range producedResults { //this loop will never finish because producedResults never gets closed // consolidate the results of the tasks executedTasks += resultOfTheTask }
Sie möchten den Kanal schließen, nachdem alle Goroutinen, die darauf schreiben, zurückgekehrt sind. Mit WaitGroup können Sie Folgendes erreichen:
wg:=sync.WaitGroup{} for i := 0; i < quantityOfWorkers; i++ { wg.Add(1) go func() { defer wg.Done() for taskSize := range remainingTasks { //simulate a long task time.Sleep(time.Second * time.Duration(taskSize)) //return the result of the long task producedResults <- taskSize } }() } go func() { wg.Wait() close(producedResults) }()
Das obige ist der detaillierte Inhalt vonWie schließe ich einen mit mehreren Goroutinen gefüllten Kanal, wenn alle Arbeiten erledigt sind?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!