的WithDeadline()
和WithTimeout()
函数都返回cancel
函数,文档说这些函数总是以延迟调用,例如:
func slowOperationWithTimeout(ctx context.Context) (Result, error) {
ctx, cancel := context.WithTimeout(ctx, 100*time.Millisecond)
defer cancel() // releases resources if slowOperation completes before timeout elapses
但是这个功能实际上发布了什么“资源”?
答案 0 :(得分:0)
您提供的代码示例来自the context.WithTimeout
documentation,此处稍作修改:
func slowOperationWithTimeout(parentContxt context.Context) (Result, error) {
childContext, cancel := context.WithTimeout(parentContxt, 100*time.Millisecond)
defer cancel() // releases resources if slowOperation completes before timeout elapses
return slowOperation(childContext)
}
(此处我已重新命名为ctx
,以明确我在谈论的内容,在实际代码中,最好只使用ctx
,因为您不需要&# 39; t想要或需要区分父/子上下文。)
调用返回的取消函数(至少)做了两件重要的事情。
首先,它关闭childContext.Done()
返回的频道。例如,如果slowOperation
在具有该上下文(或[宏]子上下文)的goroutine中启动了某些内容,则可能会导入此内容。
其次,取消childContext
会让parentContext
忘记它。
在局部变量中有子上下文的引用,在其所有子项的父列表中有另一个引用(并且任何引用slowOperation
可能保留)。如果在不再需要它时它没有被取消,那么父母会浪费空间来保持它,直到子环境最终超时并取消它自己,以及其他可能延迟子环境的事情,以及它。完成垃圾收集的渠道。
在取消之前,上下文实现(或未来的更改)也可以使用其他资源。 如果文档说你应该做某事,那就去做吧(即使它在当前的实现中什么都不做)。 从这个意义上讲,答案是"为什么?"对于这样的事情很简单,"因为文档说的是使用它的正确方法"。