Warten Sie, bis die Kündigung von n goroutines
Brauche ich eine riesige Menge von goroutines und warten auf Ihre Kündigung. Die intuitive Art und Weise, scheint ein Kanal zu warten, bis alle fertig sind :
package main
type Object struct {
//data
}
func (obj *Object) Update(channel chan int) {
//update data
channel <- 1
return
}
func main() {
channel := make(chan int, n)
list := make([]Object, n, m)
for {
for _, object := range list {
go object.Update(channel)
}
for i := 0; i < n; i++ {
<-channel
}
//now everything has been updated. start again
}
}
Aber das problem ist, dass die Menge der Objekte und damit die Menge der goroutines ändern könnte. Ist es möglich, ändern Sie die Puffergröße ein Kanal ?
Gibt es vielleicht eine elegantere Möglichkeit das zu tun ?
- Sie könnte den Puffer in jeder iteration, aber möchten Sie vielleicht, zu betrachten, WaitGroup.
- tjameson, vielen Dank für die schnelle Hilfe. Das sieht wirklich gut aus. Sie wollen vielleicht machen Sie es eine Antwort.
- Getan, mit ein Beispiel =D
- möglich, Duplikat der Wie warten Sie, bis alle goroutines zu beenden, ohne mit der Zeit.Schlafen?
Du musst angemeldet sein, um einen Kommentar abzugeben.
Ich verwendet habe, WaitGroup als eine Lösung für dieses problem. Übersetzen Sie Ihre aktuelle code, mit einigen logs deutlich zu machen, was passiert:
defer wg.Done()
am AnfangUpdate
aber nur im Fall, dass die Funktion wächst und gewinnt eine baldige Rückkehr irgendwann in der Zukunft.Diese Aufgabe nicht gerade trivial, es ist ganz einfach, Schreibe einen buggy ein. Ich empfehle eine fertige Lösung in der stdlib -
sync.WaitGroup
. Zitat aus dem link:@tjameson hat einen tollen job zu erklären, wie zu verwenden
WaitGroup
, gewusst wie: übergeben Sie einen Verweis auf IhreWaitGroup
Objekt Ihrer Funktion. Die eine änderung, die ich machen würde, um sein Beispiel ist der Hebeldefer
wenn SieDone
. Ich denke, dasdefer ws.Done()
sollte die erste Anweisung in der Funktion.Ich mag
WaitGroup
's Einfachheit. Allerdings gefällt mir nicht, dass wir übergeben die Referenz auf die goroutine denn das würde bedeuten, dass die Parallelität Logik wäre gemischt mit Ihrer business-Logik.So kam ich auf diese generische Funktion um dieses problem zu lösen für mich:
Also dein Beispiel konnte auf diese Weise gelöst werden:
Wenn Sie möchten, es zu benutzen, finden Sie es hier https://github.com/shomali11/util