安全地取消 Boost ASIO Deadline Timer
提供的代码旨在在单独的线程中安全地取消 boost::asio::basic_waitable_timer 。但是,由于潜在问题,取消似乎无法按预期进行。
了解问题:
问题源于以下事实:所提供的代码尝试使用post函数取消定时器,该函数将取消操作添加到定时器的io_service的事件队列中。这种方法是有问题的,因为如果在执行取消操作之前计时器已经过期,则取消操作将被忽略,从而有效地使计时器处于活动状态。
解决问题:
为了解决这个问题,我们需要设计一种强大的方法来取消计时器,无论其当前状态如何。一种有效的方法是为计时器的到期时间点引入一个哨兵值,该值表示无效状态。通过在取消过程中将计时器的到期时间设置为该哨兵值,我们可以确保即使在取消之前计时器已到期,也会将其置于无效状态,从而有效阻止任何进一步的异步操作。
修改代码:
实现哨兵值方法:
<code class="cpp">timer.get_io_service().post([](){ std::cerr << "tid: " << std::this_thread::get_id() << ", cancelling in post\n"; // Cancel: timer.expires_at(Timer::clock_type::time_point::min()); });</code>
完成处理程序处理:
在完成处理程序中,检查哨兵值以检测关闭:
<code class="cpp">void handle_timeout(const boost::system::error_code& ec) { if (!ec) { started = true; 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"; } } else if (ec != boost::asio::error::operation_aborted) { std::cerr << "tid: " << std::this_thread::get_id() << ", handle_timeout error " << ec.message() << "\n"; } }</code>
通过哨兵值方法,您现在可以可靠地取消计时器,即使计时器已经过期。
以上是如何在单独的线程中可靠地取消 Boost ASIO Deadline Timer?的详细内容。更多信息请关注PHP中文网其他相关文章!