过往使用中对Asio.timer的使用出现过几次错乱使用特地在此记录一下
- ioservice 先析构,timer析构后调用cancel时调用到service相关方法导致crash,用完timer构造的时候就传入了ioservice的引用
SPtr<ASIO_TIMER> timer, timer2;
{
ASIO_SERVICE io;
timer = MAKESHARED<ASIO_TIMER>(io, boost::posix_time::seconds(10));
timer->async_wait([](BOOST_EC ec) {
if (!ec)
{
printf("1 timeout\n");
}
else
{
printf("1 err %s\n", ec.message().c_str());
}
});
timer2 = MAKESHARED<ASIO_TIMER>(io, boost::posix_time::seconds(5));
timer2->async_wait([&timer, &timer2](BOOST_EC ec) {
if (!ec)
{
printf("2 timeout\n");
}
else
{
printf("2 err %s\n", ec.message().c_str());
}
});
std::thread thd([&io] {
BOOST_EC ec;
auto sz = io.run(ec);
ec.message();
});
thd.join();
}
//这里Crash
timer = nullptr;
timer2 = nullptr;
- ioservice run的线程就是timer触发回调执行的线程,没有boost::asio::io_context::work的情况下无需单独调用ioservice::stop来结束线程,只需要cancel每一个timer或者析构这个timer(触发回调errormessage<Operation canceled>),ioservice::run 就执行完成。提前stop了ioservice timer的回调不会被触发。
- 稳定时钟可以采用 boost::asio::steady_timer 和 boost::asio::chrono::milliseconds计时,不受系统时钟修改影响。