我处于一个长时间运行的可取消函数中,该函数具有永远循环。
我需要检查上下文是否已关闭。
go func(){
for {
if ctx.Err() != nil { return }
// do work
}
}()
vs
go func(){
for {
select {
case <-ctx.Done():
return
default:
}
// do work
}
}()
两者有区别吗?
我猜测检查 ctx.Err() 对于并发访问是安全的https://golang.org/src/context/context.go#L370 https://golang.org/src/context/context.go#L370所以它们看起来是相同的,给定一个封闭的上下文总是会设置 Err 。
来自context.Context
文档 https://golang.org/pkg/context/#Context:
如果 Done 尚未关闭,Err 返回 nil。
如果 Done 关闭,Err 返回一个非零错误并解释原因
通过扩展,我们可以说您的第一个样本正在检查是否Done
关闭了。鉴于完成通道的约定,它们应该只被关闭,并且永远不会向它们发送任何值,我们可以说您的第二个示例也在检查是否Done
关闭了。
因此,我们可以说这两个代码示例在功能上是等效的。我们之所以采用不同的检查方法是因为每种方法都有一些好处:
-
Err()
是立即检查并给出错误信息。
-
Done()
是一个通道,因此可以等待或使用select
case.
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)