Attendre la terminaison de n goroutines
J'ai besoin de lancer une énorme quantité de goroutines et attendre la cessation de leur emploi. La manière intuitive semble utiliser un canal d'attendre jusqu'à ce que tous d'entre eux sont finis :
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
}
}
Mais le problème est que la quantité d'objets et, par conséquent, le montant des goroutines pourrait changer. Est-il possible de changer la taille de la mémoire tampon d'un canal ?
Est là peut-être une façon plus élégante de le faire ?
Vous pourrait réaffecter à chaque itération, mais vous pouvez regarder la WaitGroup.
tjameson, merci pour l'aide rapide. Qui a l'air vraiment bon. Vous souhaitez peut-être une réponse.
Fait, avec un exemple =D
double possible de Comment attendre pour tous les goroutines à la fin sans l'aide de temps.Le sommeil?
tjameson, merci pour l'aide rapide. Qui a l'air vraiment bon. Vous souhaitez peut-être une réponse.
Fait, avec un exemple =D
double possible de Comment attendre pour tous les goroutines à la fin sans l'aide de temps.Le sommeil?
OriginalL'auteur lhk | 2013-05-16
Vous devez vous connecter pour publier un commentaire.
J'ai utilisé WaitGroup comme une solution à ce problème. La traduction de votre code actuel, avec quelques journaux pour le rendre clair ce qui se passe:
defer wg.Done()
au début deUpdate
si ce n'est que dans le cas où la fonction se développe et gagne un début de retour à un certain moment dans l'avenir.Ou dans le cas où il y a une panique ou de quelque chose.
OriginalL'auteur beatgammit
Cette tâche dans pas exactement banal, mais c'est assez facile à écrire un buggy. Je recommande d'utiliser un prêt de solution toute faite dans la stdlib -
sync.WaitGroup
. En citant le lien:vous incrémenter le compteur lorsque vous démarrez chaque goroutine, donc cette solution est encore la meilleure solution lorsque vous ne connaissez pas le numéro de goroutines vous allez commencer.
OriginalL'auteur zzzz
@tjameson a fait un excellent travail en expliquant comment utiliser
WaitGroup
, comment passer d'une référence à votreWaitGroup
objet à votre fonction. Le seul changement que j'aimerais apporter à son exemple est l'effet de levierdefer
lorsque vous êtesDone
. Je pense que cedefer ws.Done()
doit être la première instruction dans votre fonction.J'aime
WaitGroup
's de la simplicité. Cependant, je n'aime pas que nous avons besoin de passer la référence à la goroutine, car cela signifierait que la simultanéité de la logique serait mélangé avec une logique d'entreprise.Alors je suis venu avec cette fonction générique pour résoudre ce problème pour moi:
De sorte que votre exemple ne pouvait être résolu de cette façon:
Si vous souhaitez l'utiliser, vous pouvez le trouver ici https://github.com/shomali11/util
OriginalL'auteur Raed Shomali