Comment puis-je savoir si un goroutine est fait, sans bloquer?
-
20-09-2019 - |
Question
Tous les exemples que je l'ai vu jusqu'à présent impliquent le blocage pour obtenir le résultat (via l'opérateur <-chan
).
Mon approche actuelle consiste à faire passer un pointeur vers une struct:
type goresult struct {
result resultType;
finished bool;
}
que le goroutine écrit à la fin. Ensuite, il est une simple question de vérifier finished
chaque fois que pratique. Avez-vous des meilleures alternatives?
Qu'est-ce que je vise vraiment est un système de logement de signal de style Qt. J'ai une intuition la solution aura l'air trivial (chan
s ont beaucoup de potentiel inexploité), mais je ne suis pas encore assez familier avec la langue pour comprendre.
La solution
Vous pouvez utiliser le modèle "virgule, ok" (voir leur page sur « go efficace « ):
foo := <- ch; // This blocks.
foo, ok := <- ch; // This returns immediately.
Autres conseils
Sélectionnez les états vous permet de vérifier plusieurs canaux à la fois, en prenant une branche aléatoire ( de ceux où la communication est en attente):
func main () {
for {
select {
case w := <- workchan:
go do_work(w)
case <- signalchan:
return
// default works here if no communication is available
default:
// do idle work
}
}
}
Pour tout envoi et de réception expressions dans la déclaration « select », les expressions de canal sont évalués, ainsi que toutes les expressions qui apparaissent sur le côté droit de send expressions, dans l'ordre de haut en bas. Si l'une des opérations résultant peut procéder, une est choisie et la communication correspondante et déclarations sont évaluées. Autrement, s'il y a un cas par défaut, que exécute; sinon, les blocs d'instructions jusqu'à ce que l'une des communications peut complète.
Vous pouvez également utiliser le tampon de canal pour voir si elle contient quelque chose en utilisant len:
if len(channel) > 0 {
// has data to receive
}
Ce ne touche pas le tampon de canal, contrairement à foo, gotValue := <- ch
qui supprime une valeur lorsque gotValue == true
.