Maison >développement back-end >Golang >Un moyen sûr de mettre fin à un goroutine en boucle infinie ?
J'ai une goroutine qui fait office d'auditeur. Le flux d'entrée arrive dans un tampon channel
,我希望我的 goroutine 处理传入该通道的数据。然而,有时 channel
可能会暂时没有数据输入。如果 channel
qui n'a rien à offrir pendant une seconde et je veux que ma goroutine fasse quelque chose de différent. La fonction ressemble à ceci :
func main () { var wg sync.WaitGroup arr := make([]*myObject, 0) wg.Add(1) go listener(c, arr, &wg) for { // sending stuff to c } } func listener(c chan *myObject, arr []*myObject, wg *sync.WaitGroup) { for { select { case value := <- c: arr = append(arr, value) case <- time.After(1 * time.Second): fmt.Println(arr) } }
Le problème est que je veux voir imprimé tout ce qui passe par ce canal. Si la position de main
突然结束,可能 arr
中还剩下一些东西还没有打印出来,我就看不到了。所以我需要确保这个goroutine在程序结束之前处理完通道中的所有数据。我认为,这意味着我需要使用 WaitGroup
并使用 Wait()
来确保程序在我的 goroutine 完成需要执行的操作之前不会关闭。 但我不知道在我的 WaitGroup
上调用 Done()
.
En gros, j'ai besoin d'un moyen sûr de "mettre en pause" la goroutine avant la fin du programme et d'imprimer ce qui reste. Comment puis-je faire ceci?
Pour aggraver les choses, pour des choses comme les tests unitaires, j'envoie moi-même des données au canal et après avoir envoyé une certaine quantité, je souhaite voir le tableau. Cependant, si je vérifie simplement le tableau juste après le code qui envoie les données au canal, la goroutine n'a peut-être pas encore eu la possibilité de traiter toutes les données. Dans ce cas, je veux attendre que la goroutine traite toutes les données que j'envoie, puis je veux la mettre en pause et lui demander de me montrer le tableau. Mais comment puis-je savoir quand la goroutine a terminé le traitement ? Je pourrais sleep
attendre un moment, lui donner une chance de terminer, puis m'arrêter et le regarder, mais cela semble plutôt compliqué. Je pense qu'il existe une bonne pratique pour résoudre ce problème, mais je ne l'ai pas encore compris.
Voici quelques idées que j'avais, aucune d'entre elles n'a fonctionné.
à l'infini for
循环之外调用 Done()
. Cela ne fonctionne pas car à ma connaissance, le code n'est pas accessible.
En délai d'attentecase
中调用Done()
. Cela ne fonctionne pas car après le délai d'attente, il peut y avoir plus de données en route et je veux que ma goroutine continue d'écouter.
Modifiez l'auditeur pour qu'il revienne lorsque la chaîne est fermée. Appelez wg.Done() au retour :
func listener(c chan *myObject, arr []*myObject, wg *sync.WaitGroup) { defer wg.Done() for { select { case value, ok := <- c: if !ok { return } arr = append(arr, value) case <- time.After(1 * time.Second): fmt.Println(arr) } }
Modifiez main pour fermer la chaîne une fois l'envoi terminé. Attendez que la goroutine soit terminée avant de revenir du principal.
var wg sync.WaitGroup arr := make([]*myObject, 0) wg.Add(1) go listener(c, arr, &wg) for { // sending stuff to c } close(c) wg.Wait()
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!