Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to know if goroutine still exist?

Tags:

go

goroutine

Is there a comparable function like java Thread.isAlive() for goroutine?

I am trying to spawn some goroutine that is meant to be long living threads, but I am afraid that goroutine can die mid process, is there a check that I can do in my main thread to see if goroutine is alive?

like image 881
user10714010 Avatar asked Mar 21 '19 04:03

user10714010


Video Answer


1 Answers

The best way is not to know if it's till alive but to know when it dies so you can restart it.

You can do that by setting a defer with a recover on your goroutine which would write to a channel signaling the death of the goroutine. Then on the main goroutine, you read from that channel, and whenever something is read, you restart a goroutine. You could identify wich goroutine failed by returning a struct containing the goroutine id and the error.

Example:

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
}
like image 146
Francois Avatar answered Oct 11 '22 09:10

Francois