我有一个使用context.WithTimeout
的简单实现,或多或少像:
ctx, cancelFn := context.WithTimeout(context.Background(), time.Duration(time.Minute*1))
go func() {
// do something
cancelFn()
}()
select {
case <-ctx.Done():
// ...
return
}
当我监控当前存在的goroutine的数量时(使用runtime.NumGoroutines()
),似乎无论何时调用WithTimeout()
函数,它都会在内部创建一个goroutine来跟踪时间并最终取消上下文(如果你看一下内部(https://github.com/golang/go/blob/master/src/context/context.go#L401和https://github.com/golang/go/blob/master/src/time/sleep.go#L170),这是有道理的。
但是,当上下文完成并且达到case语句时,goroutine不会被释放。它似乎永远在运行,资源没有正确发布。
如果我更改实现以使用更简单的超时版本,不 context.WithTimeout()
,或多或少像:
select {
case <-time.After(time.Minute*1):
// ...
return
}
然后,goroutines的数量首先是预期的,似乎没有任何泄漏。
可能是什么问题?我错过了什么?