类中实现两个异步定时器:延迟启动第二个时输出异常问题
Boost.Asio定时器生命周期异常输出问题解决
问题现象
想要实现第二个定时器在第一个启动0.5秒后运行,但当前代码执行后,第二个print对象仅输出Last num 0就终止,无法完成正常的计数逻辑;而不设置启动延迟时,两个定时器都能正常工作。
当前终端输出:
0, 1, Last num 0, 2, 3, 4, Last num 5.
问题根源
在steady_timer t的异步等待回调中创建的print pp(io)是局部变量,回调函数执行完毕后,该变量会立即被销毁。此时pp内部的定时器还没来得及触发第一次回调(或回调刚触发就因对象析构失效),因此只会调用析构函数输出Last num 0,无法执行后续计数逻辑。
而第一个print p(io)位于main函数作用域,生命周期持续到io.run()执行结束后,因此能正常完成5次计数输出。
解决方案
需要延长第二个print对象的生命周期,确保其在定时器完成所有回调前不会被销毁。推荐使用std::shared_ptr结合std::enable_shared_from_this来管理对象生命周期,让异步回调持有对象的引用,避免提前析构。
修正后的代码
#include <iostream> #include <functional> #include <memory> #include <boost/asio.hpp> class print : public std::enable_shared_from_this<print> { public: print(boost::asio::io_context& io) : timer_(io, boost::asio::chrono::seconds(1)), count_(0) { timer_.async_wait(std::bind(&print::printer, shared_from_this())); } void printer() { if (count_ < 5) { std::cout << count_ << "\n"; ++count_; timer_.expires_at(timer_.expiry() + boost::asio::chrono::seconds(1)); timer_.async_wait(std::bind(&print::printer, shared_from_this())); } } ~print() { std::cout << "Last num " << count_ << "\n"; } private: boost::asio::steady_timer timer_; int count_; }; int main() { boost::asio::io_context io; print p(io); // 设置0.5秒延迟,符合需求 boost::asio::steady_timer t(io, boost::asio::chrono::milliseconds(500)); t.async_wait([&io](const boost::system::error_code& ec) { if (!ec) { // 用shared_ptr管理对象,延长生命周期 auto pp = std::make_shared<print>(io); } }); io.run(); }
关键修正点
- 继承
enable_shared_from_this:让print类继承std::enable_shared_from_this<print>,这样可以在成员函数中通过shared_from_this()获取对象的shared_ptr,确保每次异步回调都持有对象的引用,避免对象被提前销毁。 - 用
shared_ptr创建对象:在回调中使用std::make_shared<print>(io)创建对象,shared_ptr会自动管理生命周期,直到所有回调执行完毕后才销毁对象。 - 调整延迟时间:将第二个定时器的延迟从2秒改为500毫秒,满足“第二个定时器在第一个启动0.5秒后开始运行”的需求。
预期输出
修正后两个定时器会交替输出计数,直到各自完成5次循环,最终输出析构信息:
0 1 0 2 1 3 2 4 3 Last num 5 4 Last num 5
内容的提问来源于stack exchange,提问作者zxctatar
相关产品推荐
相关产品推荐

