本文将通过研究提供的代码示例及其相关内容,深入探讨安全取消 boost::asio::basic_waitable_timer 的主题意外行为。
目标是使用向 I/O 服务发布取消请求的推荐方法来取消截止时间计时器:
<code class="cpp">timer.get_io_service().post([&]{timer.cancel();})</code>
然而,提供的代码似乎并没有按预期终止计时器。
代码使用 I/O 服务、截止时间计时器和线程的组合来创建一个计时器同时启动和取消的场景。
在计时器已过期的情况下尝试取消时会出现此问题。在这种情况下,发布的 cancel() 请求不会生效。因此,计时器的完成处理程序继续触发,导致主线程无限期地阻塞。
为了解决这个问题,我们需要一种方法来检测计时器是否没有被取消。一种方法是使用计时器的到期时间点,并在发起取消时为其分配一个特殊的“无效”值:
<code class="cpp">timer.get_io_service().post([](){ timer.expires_at(Timer::clock_type::time_point::min()); });</code>
在完成处理程序中,如果到期时间点设置为此无效值,处理程序可以识别出计时器未取消并相应地进行处理:
<code class="cpp">void handle_timeout(const boost::system::error_code& ec) { if (timer.expires_at() != Timer::time_point::min()) { timer.expires_from_now(std::chrono::milliseconds(10)); timer.async_wait(&handle_timeout); } else { std::cerr << "handle_timeout: detected shutdown\n"; } }</code>
虽然 Boost Asio 中取消异步操作通常是安全的,但考虑情况也很重要其中,在接收到取消请求之前操作可能已经完成。使用额外的逻辑来检测和处理此类场景可确保异步任务的稳健取消。
以上是我如何安全地取消 Boost Asio 截止计时器,即使它已经过期?的详细内容。更多信息请关注PHP中文网其他相关文章!