5
votes

Comment savoir si la goroutine existe encore?

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 commentaires

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.


4 Réponses :


3
votes

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.


0 commentaires

0
votes

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


0 commentaires

4
votes

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 {}
}


0 commentaires

11
votes

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
}


1 commentaires