![](/img/trans.png)
[英]boost::asio::deadline_timer cancel() method is not calling timer handler
[英]How do I properly cancel a Boost deadline_timer from a destructor (in a multithreaded environment)?
我有一个名为Timer
的 class 公开了两个名为start
和stop
的方法。
void Timer::start() {
_enabled.store(true, std::memory_order::memory_order_release);
_timer.expires_from_now(_delay);
_timer.async_wait(
std::bind(
&Timer::tick,
this,
std::placeholders::_1
));
}
void Timer::stop() {
_enabled.store(false, std::memory_order::memory_order_release);
_timer.cancel();
}
void Timer::tick(const boost::system::error_code& error) {
if (error) return;
if (!_enabled.load(std::memory_order::memory_order_acquire)) return;
try {
_task();
} catch (...) {}
if (_enabled.load(std::memory_order::memory_order_acquire)) {
_timer.expires_from_now(_delay);
_timer.async_wait(
std::bind(
&Timer::tick,
this,
std::placeholders::_1
));
}
}
另一个使用Timer
实例的 class(处理程序在 ThreadPool 实例中的某个其他线程上执行)在其析构函数中调用stop
。 从Boost 文档中,现在可能会调用处理程序并且这两个函数将同时执行,并且处理程序可能会尝试访问已释放的资源。
SomeOtherClass::~SomeOtherClass() {
_timer.stop();
// somehow wait for _timer handler to execute
// delete[] some_thing;
// other destructive things
}
无论如何要等待处理程序完成执行? 我整天都在摸不着头脑,我对 Boost 很陌生,所以也许我犯了一个设计缺陷。 任何帮助将不胜感激,谢谢。
一种模式是为您的Timer
提供一个 shared_ptr (通过使用std::enable_shared_from_this
)。
这样,只要处理程序尚未执行,您就可以使计时器保持活动状态(通过保留绑定到处理程序的共享指针的副本)。
其他解决方案可能是:
std::list
),您可以在不再需要它们时手动删除它们io_service
,因此您可以join
线程以等待io_service
上的工作。根据您的用例/负载模式,一种方法会比其他方法更好。
样品:
std::list
来管理具有参与异步操作的服务对象的对象的生命周期(在本例中为 Session: 如何将 boost asio tcp 套接字传递给线程以向客户端或服务器发送心跳shared_from_this
: 使用 Boost.Asio 的简单服务器会引发异常我选择了具有一些对比方法的答案(有些不使用 Boost Asio),因此您可以看到权衡取舍以及方法之间的变化。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.