boost 定时器

1 篇文章 0 订阅

参考资料:

basic_waitable_timer::expires_after - 1.66.0 (boost.org)

#include <boost/asio.hpp>
#include <boost/asio/system_timer.hpp>
#include <boost/bind.hpp>
#include <boost/make_shared.hpp>
#include <boost/shared_ptr.hpp>
#include <chrono>
#include <iostream>
#include <memory>
#include <thread>

using namespace std;

#define PRINTF_NOW()                                         \
    do                                                       \
    {                                                        \
        time_t timep;                                        \
        time(&timep);                                        \
        std::cout << "\033[31m" << __FUNCTION__ << "\033[0m" \
                  << ",Time: " << ctime(&timep) << " ";      \
    } while (0)

class DataAccessor
{
private:
    typedef boost::shared_ptr<boost::asio::system_timer> SystemTimerPtr;
    boost::asio::io_context _context;
    SystemTimerPtr _timer;
    boost::uint64_t _t;

    /* 数据 */
    bool _running = false;
    std::thread _saveThread;  // 保存数据的线程

public:
    ~DataAccessor()
    {
        _context.stop();
        PRINTF_NOW();
        _saveThread.join();
    }

    void setTimer(boost::uint64_t t)
    {
        PRINTF_NOW();

        _t = t;
        if (!_running)
        {
            _timer =
                boost::make_shared<boost::asio::system_timer>(_context, std::chrono::seconds(_t));
            std::cout << "_t = " << _t << std::endl;
            _timer->async_wait(boost::bind(&DataAccessor::handler, this, boost::placeholders::_1));
        } else
        {
            std::size_t n = _timer->expires_after(std::chrono::seconds(_t));
            // _timer->cancel_one();

            std::cout << __FUNCTION__ << " " << n << " asynchronous operations were cancelled."
                      << std::endl;
            _timer->async_wait(boost::bind(&DataAccessor::handler, this, boost::placeholders::_1));
        }
    }

    void run()
    {
        PRINTF_NOW();

        if (_running)
        {
            return;
        }
        _running = true;
        std::thread th([&]() {
            try
            {
                auto cnt = _context.run();
                std::cout << "cnt: " << cnt << std::endl;
            } catch (const std::exception& ex)
            {
                std::cerr << "DataAccessor run failed.." << std::endl;
            }
        });
        _saveThread.swap(th);
    }

    void handler(const boost::system::error_code& ec)
    {
        PRINTF_NOW();

        if (!ec)
        {  // 重启定时器
            cout << "TimeOut: " << _t << endl;
            std::size_t n = _timer->expires_after(std::chrono::seconds(_t));
            std::cout << __FUNCTION__ << " " << n << " asynchronous operations were cancelled."
                      << std::endl;
            _timer->async_wait(boost::bind(&DataAccessor::handler, this, boost::placeholders::_1));
        }
    }
};

int main()
{
    DataAccessor da;
    da.setTimer(3);
    da.run();

    this_thread::sleep_for(chrono::seconds(10));

    da.setTimer(4);
    this_thread::sleep_for(chrono::seconds(10));
}

运行结果:

setTimer,Time: Tue Mar 12 14:00:31 2024
 _t = 3
run,Time: Tue Mar 12 14:00:31 2024
 handler,Time: Tue Mar 12 14:00:34 2024
 TimeOut: 3
handler 0 asynchronous operations were cancelled.
handler,Time: Tue Mar 12 14:00:37 2024
 TimeOut: 3
handler 0 asynchronous operations were cancelled.
handler,Time: Tue Mar 12 14:00:40 2024
 TimeOut: 3
handler 0 asynchronous operations were cancelled.
setTimer,Time: Tue Mar 12 14:00:41 2024
 setTimer 1 asynchronous operations were cancelled.
handler,Time: Tue Mar 12 14:00:41 2024
 handler,Time: Tue Mar 12 14:00:45 2024
 TimeOut: 4
handler 0 asynchronous operations were cancelled.
handler,Time: Tue Mar 12 14:00:49 2024
 TimeOut: 4
handler 0 asynchronous operations were cancelled.
~DataAccessor,Time: cnt: 6
Tue Mar 12 14:00:51 2024

image.png

对于每次调用 async_wait() ,提供的处理程序将被调用一次。该处理程序将在以下情况下被调用:

  1. 计时器已过期;
  2. 计时器被取消,在这种情况下,处理程序将传递错误代码。

第 10 s setTimer 调用 expires_after 函数, 重新设置定时到期时间。同时取消的 1 个异步等待操作。可以看到,在第二次设置定时器超时时间时,原来的计时器被取消,handler 被立即调用,且错误码不为 0。

context 调用 stop() 时,handler 不会被调用。

  • 5
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

AWei_i_i

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值