Existe-t-il une fonction comparable comme java Thread.isAlive ()
pour goroutine?
J'essaie de créer une goroutine qui est censée être de longs fils vivants, mais j'ai peur que la goroutine puisse mourir au milieu du processus, y a-t-il une vérification que je peux faire dans mon fil principal pour voir si la goroutine est vivante? < / p>
4 Réponses :
Existe-t-il une fonction comparable comme java Thread.isAlive () pour goroutine?
Non. Vous devez repenser votre solution. Les goroutines n'ont aucune identité et ne sont en aucun cas accessibles.
Oui, goroutine a un identifiant unique dans golang, vous pouvez le trouver dans le package d'exécution.
Mais goroutineID ne doit pas être utilisé à moins de déboguer.
Si vous souhaitez surveiller une goroutine, le meilleur moyen est de créer un canal ou un journal
Non,
Vous pouvez implémenter vous-même une méthode channel / Sync, pour vérifier si une goroutine spécifique est active.
Vous pouvez également obtenir le nombre de Goroutines en utilisant runtime.NumGoroutine ()
, comme ceci:
package main import ( "fmt" "runtime" "time" ) func main() { fmt.Println(runtime.NumGoroutine()) // 1 go fun2() fmt.Println(runtime.NumGoroutine()) // 2 go fun3() fmt.Println(runtime.NumGoroutine()) // 3 time.Sleep(120 * time.Millisecond) fmt.Println(runtime.NumGoroutine()) // 2 } func fun3() { time.Sleep(100 * time.Millisecond) } func fun2() { select {} }
Le meilleur moyen n'est pas de savoir s'il est encore vivant mais de savoir quand il meurt pour pouvoir le redémarrer.
Vous pouvez le faire en définissant un différer
avec un recover
sur votre goroutine qui écrirait sur un canal signalant la mort du goroutine. Ensuite, sur le goroutine principal, vous lisez à partir de ce canal, et chaque fois que quelque chose est lu, vous redémarrez un goroutine. Vous pouvez identifier quel goroutine a échoué en renvoyant une structure contenant l'identifiant de goroutine et l'erreur.
Exemple:
package main import "fmt" // number of desired workers const nWorkers = 10 func main() { // make a buffered channel with the space for my 10 workers workerChan := make(chan *worker, nWorkers) for i := 0; i < nWorkers; i++ { i := i wk := &worker{id: i} go wk.work(workerChan) } // read the channel, it will block until something is written, then a new // goroutine will start for wk := range workerChan { // log the error fmt.Printf("Worker %d stopped with err: %s", wk.id, wk.err) // reset err wk.err = nil // a goroutine has ended, restart it go wk.work(workerChan) } } type worker struct { id int err error } func (wk *worker) work(workerChan chan<- *worker) (err error) { // make my goroutine signal its death, wether it's a panic or a return defer func() { if r := recover(); r != nil { if err, ok := r.(error); ok { wk.err = err } else { wk.err = fmt.Errorf("Panic happened with %v", r) } } else { wk.err = err } workerChan <- wk }() // do something // ... return err }
Joli modèle: +1: J'en ai fait une idée principale gist.github.com/fentas/04c1e59f6cde0defa78f16d8 / a> après quelques modifications.
Une explication pour un vote défavorable serait très appréciée, car elle me permet d'améliorer ou de clarifier le problème :)
"J'ai peur que la goroutine puisse mourir à mi-chemin." Pourquoi? Les goroutines ne s'arrêtent pas au hasard. Ils se terminent s'ils atteignent une instruction return, ou la fin du corps de la fonction, ou si une panique survient (ce qui bloque généralement le programme de toute façon).
«J'ai peur que la goroutine puisse mourir à mi-chemin» a définitivement besoin de plus d'explications. Il n'y a normalement aucune raison d'avoir une telle peur.
si vous êtes préoccupé par une panique (bien que l'on doive rarement paniquer en go) - on peut implémenter un gestionnaire de panique et récupérer (http.Handler le font, c'est-à-dire qu'ils ne veulent pas d'un mauvais gestionnaire de requêtes http détruisant un serveur Web entier ). Mais en répétant les autres commentaires ici, les routines de départ ne meurent pas, elles se terminent simplement.