boost steady_timer使用

异步使用定时器

代码:

void print(const boost::system::error_code& e)
{
   std::cout << "Hello!" << std::endl;
}

int main()
{
    boost::asio::io_context io_ctx;
    boost::asio::steady_timer t(io_ctx, boost::asio::chrono::seconds(5));
    t.async_wait(&print);
    io_ctx.run();
    return 0;
}

注意

  • asio库能保证只有当前调用io_context::run()的线程调用回调函数。
  • 除非io_context::run()被调用,否则异步等待完成的回调函数永远不会被调用。

为回调函数绑定参数(实现重复定时)

为了实现重复定时,需要在回调函数里修改steady_timer的过期时间,因此要把steady_timer传给回调函数:

void print(const boost::system::error_code& e, boost::asio::steady_timer *t, int *count)
{
    std::cout << "Hello!" << std::endl;
    if(*count < 10) {
        ++*count;
        t->expires_at(t->expiry() + boost::asio::chrono::seconds(1));
        t->async_wait(boost::bind(print, boost::asio::placeholders::error, t, count));
    }
}

int main()
{
    int count = 0;
    boost::asio::io_context io_ctx;
    boost::asio::steady_timer t(io_ctx, boost::asio::chrono::seconds(1));
    t.async_wait(boos::bind(print, boost::asio::placeholders::error, &t, &count));
    io_ctx.run();
    std::cout << "timer: " << count << std::endl;
    return 0;
}

使用成员函数作为回调

代码:

class Timer
{
    public:
        Timer(boost::asio::io_context& io_ctx): t(io_ctx, boost::asio::chrono::seconds(1)), count(0)
        {
            t.async_wait(boost::bind(Timer::print, this, boost::asio::placeholders::error));
        }
    private:
        void print(boost::system::error_code& e)
        {
            std::cout << "Hello!" << std::endl;
            if(count < 100) {
                ++count;
                t.expires_at(t.expiry() + boost::asio::chrono::miliseconds(100));
                t.async_wait(boost::bind(Timer::print, this, boost::asio::placeholders::error));
            }
        }
    private:
        boost::asio::steady_timer t;
        unsigned int count;
};

int main()
{
    boost::io_context io_ctx;
    Timer timer(io_ctx);
    io_ctx.run();
    
    return 0;
}

在多线程程序中处理定时回调(多线程处理多个定时任务)

由一个线程来调用io_context::run()导致了回调函数不能够并发的运行。为了避免这个限制,一个直接的方法就是用线程池来调用io_context::run()。然而,为了能够并发的处理回调,还需要一种方法来同步回调对共享的非线程安全的资源的访问。

例子:
假设有3种定时任务,分别是1秒、2秒、3秒,定义3个,代码:

class Timer
{   
    public:
        Timer(boost::asio::io_context& io_ctx, boost::asio::io_context::strand& strand_1, unsigned int timeout_, unsigned int id_): id(id_), count(0), timeout(timeout_), t(io_ctx, boost::asio::chrono::milliseconds(timeout_)), strand_(strand_1)
    {   
        t.async_wait(boost::asio::bind_executor(strand_, boost::bind(&Timer::OnTimerCallBack, this)));
    }
    private: 
        void OnTimerCallBack()
        {   
            if(count < 10) {
                ++count;
                std::cout << " Timer[" << id << "]: [" << count << "]" << std::endl;
                t.expires_at(t.expiry() + boost::asio::chrono::milliseconds(timeout));
                t.async_wait(boost::asio::bind_executor(strand_, boost::bind(&Timer::OnTimerCallBack, this)));
            }
        }
    private:
        unsigned int id;
        unsigned int count;
        unsigned int timeout;
        boost::asio::steady_timer t;
        boost::asio::io_context::strand& strand_;
};

int main()
{
    boost::asio::io_context io_ctx;
    boost::asio::io_context::strand strand_(io_ctx);
    Timer timer1(io_ctx, strand_, 1000, 1);
    Timer timer2(io_ctx, strand_, 2000, 2);
    Timer timer3(io_ctx, strand_, 3000, 3);
    boost::thread t1(boost::bind(&boost::asio::io_context::run, &io_ctx));
    boost::thread t2(boost::bind(&boost::asio::io_context::run, &io_ctx));
    t1.join();
    t2.join();

    return 0;
}

你可能感兴趣的:(boost,steady_timer)