go - 如何知道 goroutine 是否还存在?

标签 go goroutine

goroutine 有类似 java Thread.isAlive() 的函数吗?

我正在尝试生成一些 goroutine,该 goroutine 应该是长期存在的线程,但我担心 goroutine 会在进程中途死亡,是否可以在我的主线程中检查 goroutine 是否还活着?

最佳答案

最好的方法不是知道它是否还活着,而是知道它什么时候死了,这样你就可以重新启动它。

您可以通过在您的 goroutine 上设置一个 defer 和一个 recover 来做到这一点,这将写入一个 channel ,表示 goroutine 的死亡。然后在主 goroutine 上,你从那个 channel 读取,每当读取到某些东西时,你就重新启动一个 goroutine。您可以通过返回包含 goroutine id 和错误的结构来确定哪个 goroutine 失败。

示例:

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
}

关于go - 如何知道 goroutine 是否还存在?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55273965/

相关文章:

go - 我可以在 Golang 中基于另一个类型参数来约束一个类型参数吗?

go - 如何停止一个 goroutine

go - 处理超时并收听 channel

go - 解决 goroutines 死锁

go - 使用 go channel 的 go echo 服务器,但服务器没有回复

google-app-engine - Go例程泄漏在哪里?

go - GCP发布/订阅:使用goroutines使多个订户在一个应用程序中运行

go - 缓冲区问题不能在 http.NewRequest golang 的参数中使用 <type> 作为 io.Reader 类型

pointers - reflect.New 返回 <nil> 而不是初始化的结构

go - 最大 goroutine 数