我正在观看(不是第一次)一般使用异步:C++ 执行器之旅(第 1 部分和2),大约是 P2300。
关于取消支持,Eric Niebler 表示调用代码应该声明一个
std::stop_source
,在其上调用 get_token()
,并将结果 std::stop_token
传递给要启动的异步代码。然后,呼叫者可以随时在 request_stop
上拨打
std::stop_source
。
异步代码的作者应该编写一些内容,以保证对该请求的迅速反应。埃里克说,要做到这一点,他们可以做以下两件事之一:
std::stop_token
,我假设是通过 stop_requested()
并做出相应反应,虽然我可以很容易地想象解决方案 1,但我不太明白
“解决方案 2 会是什么样子”。
“轮询”停止状态对于消耗 CPU 的线程来说是一件好事——它们在某个循环中计算某些内容,并且时不时地检查停止状态。到目前为止,一切都很好。
但是,线程不一定使用 CPU——它们可能处于等待调用状态,等待某些事情发生。这意味着他们无法轮询任何内容。不,您不想只是在 10 毫秒超时或类似的循环中运行等待,以便它可以检查停止状态。
在许多情况下,这实际上可能是某种事件循环。在这种情况下,在停止系统中注册的回调将用于向事件循环发送“退出”事件。
如果不使用事件循环,我们仍然可以通过从外部取消等待的方式来实现等待,然后由回调触发,允许线程唤醒并做出反应(通常只是抛出异常表示取消)。
事情也可以组合起来:您的回调可以简单地唤醒线程,并且线程将在寻找实际工作之前检查停止状态。这实际上取决于线程的作用和便利性。归根结底,回调适用于仅具有停止是/否布尔值还不够的情况,并且线程需要一些涉及踢的动作来注意到停止。