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



有没有类似的函数,比如javaThread.isAlive()for goroutine?

我正在尝试生成一些旨在成为长寿命线程的 goroutine,但我担心 goroutine 会在进程中死亡,是否可以在我的主线程中进行检查以查看 goroutine 是否处于活动状态?

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

您可以通过在goroutine上设置一个带有recoverdefer来做到这一点,该将写入一个通道,发出goroutine死亡的信号。然后在主 goroutine 上,您从该通道读取,每当读取某些内容时,您都会重新启动 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
}

有没有类似的函数,比如java Thread.isAlive()的goroutine?

不。您必须重新设计您的解决方案。Goroutines 没有标识,无法以任何方式访问。

你需要自己实现它,以检查特定的goroutine是否处于活动状态,例如:


func routine(id int) {
atomic.StoreInt32(&alive[id], 1)       // set alive
defer wg.Done()                        // for main sync
defer atomic.StoreInt32(&alive[id], 0) // gone
d := rand.Intn(200)
defer func() { fmt.Println("gone:", id, "after", time.Since(t0), "d =", d) }() // show
time.Sleep(time.Duration(d) * time.Millisecond) // job
}
func main() {
for i := 0; i < max; i++ {
wg.Add(1)
go routine(i)
}
id := rand.Intn(max)
time.Sleep(time.Duration(rand.Intn(200)) * time.Millisecond)
fmt.Println(id, "is alive:", atomic.LoadInt32(&alive[id]) == 1, "after", time.Since(t0))
wg.Wait()
fmt.Println(len(alive)) // 10
}
const max = 10
var (
wg    sync.WaitGroup
alive = make([]int32, max)
t0    = time.Now()
)

输出:

gone: 5 after 25ms d = 25
gone: 4 after 47ms d = 47
gone: 0 after 56ms d = 56
gone: 9 after 59ms d = 59
gone: 7 after 81ms d = 81
1 is alive: true after 87ms
gone: 3 after 94ms d = 94
gone: 2 after 100ms d = 100
gone: 6 after 111ms d = 111
gone: 8 after 118ms d = 118
gone: 1 after 140ms d = 140
10

相关内容

最新更新