如何知道goroutine是否仍然存在?

时间:2019-03-21 04:50:42

标签: go goroutine

goroutine是否具有类似Java Thread.isAlive()的功能?

我正在尝试生成一些本来应该是长寿线程的goroutine,但是我担心goroutine会在进程中死去,是否可以在我的主线程中进行检查以查看goroutine是否还活着? / p>

4 个答案:

答案 0 :(得分:6)

最好的方法是不知道它是否还活着,而是知道它何时死亡,以便您可以重新启动它。

您可以通过在goroutine上将deferrecover设置为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 } 来做到这一点,这将写入一个表明goroutine死亡的通道。然后,在主goroutine上,您从该通道读取数据,并且每当读取某些内容时,都将重新启动goroutine。您可以通过返回包含goroutine id和错误的结构来识别gogorine失败。

示例:

pthread_cond_*

答案 1 :(得分:3)

  

goroutine是否具有类似的Java Thread.isAlive()函数?

不。您必须重新设计解决方案。 Goroutine没有身份并且无法以任何方式访问。

答案 2 :(得分:1)

不,
您可以自己实现channel / Sync方法,以检查特定的goroutine是否仍在运行。
同样,您可以使用runtime.NumGoroutine()获取Goroutine的数量,如下所示:

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

答案 3 :(得分:-1)

是的,goroutine在golang中具有唯一的ID,您可以在运行时包中找到它。

但是除非进行调试,否则不应使用goroutineID。

如果要监视一个goroutine,最好的方法是使用频道或日志