请求停止与已经停止要区分

工作不再需要时,调用者可以请求取消,以免继续占用资源或产生没有使用者的结果。但取消接口的成功返回,可能只表示请求已被接收,不能在没有进一步约定时当作工作已经结束。

Python的asyncio.Task.cancel安排向协程抛出CancelledError,任务有机会清理,也可能显式抑制该异常。因此Task.cancel不同于立即终止一条机器线程,最终取消状态需要结合任务的实际结束方式判断。

参考:[1]

用关联范围传播取消

一个操作还可能启动多个子操作。Go的Context把取消信号与截止时间向派生上下文传播,使用者可以观察Done通道结束不再需要的处理;派生取消也有助于释放关联资源。

信号并不会替任意函数执行检查。Go文档中的生成器在select中明确监听Done,再主动返回;如果程序只建立上下文却从不观察它,不能期待该上下文强行停止所有工作。

参考:[2]

清理与失败报告保持一致

Python建议协程通过try/finally执行清理,显式捕获取消后通常继续传播。TaskGroup与超时上下文依赖取消进行内部协调,完全吞掉该异常可能使外层管理逻辑失去预期的结束信号。

不同结果接口也不能混用规则。asyncio.Future可以直接进入取消状态,而concurrent.futures等执行器接口面对已经运行的任务又有各自限制。调用者应核对所用对象的取消契约,并在需要时等待实际收尾,而不是只记录一次请求就回收仍在使用的资源。

参考:[1] [3] [4]