我处于一个长期运行的可取消函数中,该函数具有一个永久循环。
我需要检查上下文是否关闭。
go func(){
for {
if ctx.Err() != nil { return }
// do work
}
}()
对
go func(){
for {
select {
case <-ctx.Done():
return
default:
}
// do work
}
}()
这两者有区别吗?
我猜测检查 ctx.Err() 对于并发访问是安全的 https://golang.org/src/context/context.go#L370所以它们看起来是一样的,给定一个封闭的上下文总是会设置 Err。
最佳答案
来自context.Context
documentation :
If Done is not yet closed, Err returns nil. If Done is closed, Err returns a non-nil error explaining why
通过扩展,我们可以说您的第一个示例正在检查 Done
是否已关闭。鉴于 done channel 的约定,它们只应关闭,并且永远不会在其上发送任何值,我们可以说您的第二个示例也在检查 Done
是否已关闭。
因此,我们可以说这两个代码示例在功能上是等效的。我们之所以有不同的检查方法是因为每种方法都有一些好处:
Err()
是立即检查并给出错误信息。Done()
是一个 channel ,因此可以在select
情况下等待或使用。
关于go - ctx.Err() vs ctx.Done() chan 关闭检查 : Is there a difference?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67439974/