C++ Boost ASIO 简单的周期性定时器?

Posted

技术标签:

【中文标题】C++ Boost ASIO 简单的周期性定时器?【英文标题】:C++ Boost ASIO simple periodic timer? 【发布时间】:2011-05-15 03:08:12 【问题描述】:

我想要一个非常简单的周期性计时器来每 50 毫秒调用一次我的代码。我可以制作一个一直休眠 50 毫秒的线程(但这很痛苦)...我可以开始研究用于制作计时器的 Linux API(但它不是可移植的)...

我希望喜欢使用 boost.. 我只是不确定这是否可能。 boost 是否提供此功能?

【问题讨论】:

【参考方案1】:

一个非常简单但功能齐全的示例:

#include <iostream>
#include <boost/asio.hpp>

boost::asio::io_service io_service;
boost::posix_time::seconds interval(1);  // 1 second
boost::asio::deadline_timer timer(io_service, interval);

void tick(const boost::system::error_code& /*e*/) 

    std::cout << "tick" << std::endl;

    // Reschedule the timer for 1 second in the future:
    timer.expires_at(timer.expires_at() + interval);
    // Posts the timer event
    timer.async_wait(tick);


int main(void) 

    // Schedule the timer for the first time:
    timer.async_wait(tick);
    // Enter IO loop. The timer will fire for the first time 1 second from now:
    io_service.run();
    return 0;

请注意,调用expires_at() 设置新的到期时间非常重要,否则计时器将立即触发,因为它的当前到期时间已经到期。

【讨论】:

@AndrewStone 我不这么认为,但如果你担心的话,你可以使用一个稳定的计时器来代替,它不会受到系统时间变化的影响。看看这里:boost.org/doc/libs/1_65_1/doc/html/boost_asio/reference/… 应该很容易移植我上面的例子来使用它。 请注意,boost::asio::io_service::run() 会阻塞线程执行,因此您无法在调用它后执行指令并期望计时器也同时触发。 为什么允许在没有'()'的情况下调用tick,即不应该是 timer.async_wait(tick()); @jaxkewl 原因是tick 没有被立即调用。相反,它的引用被传递给async_wait(),它最终会在未来调用它。 +1。 expires_at 比官方示例使用的expires_after 准确得多。 expires_after 在定时器周期中引入了偏差,在高速率下实际上变得无用。【参考方案2】:

Boosts Asio 教程的第二个例子解释了它。 你可以找到它here。

之后,check the 3rd example 看看如何以周期性的时间间隔再次调用它

【讨论】:

@PhilippLudwig 感谢您的通知。他们似乎改变了链接格式。我更新了链接 请注意,boost::asio::io_service::run() 会阻塞线程执行,因此您无法在调用它后执行指令并期望计时器也同时触发。 等等,如果 IO.run 阻塞线程执行,那么异步的意义何在?【参考方案3】:

进一步扩展这个简单的例子。它会像 cmets 中所说的那样阻塞执行,所以如果你想运行更多的 io_services,你应该像这样在一个线程中运行它们......

boost::asio::io_service io_service;
boost::asio::io_service service2;
timer.async_wait(tick);
boost::thread_group threads;
threads.create_thread(boost::bind(&boost::asio::io_service::run, &io_service));
service2.run();
threads.join_all();

【讨论】:

【参考方案4】:

由于我之前的答案有一些问题,这里是我的例子:

#include <boost/asio.hpp>
#include <boost/bind.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>
#include <iostream>

void print(const boost::system::error_code&, boost::asio::deadline_timer* t,int* count)

    if (*count < 5)
    
        std::cout << *count << std::endl;
        ++(*count);
        t->expires_from_now(boost::posix_time::seconds(1));
        t->async_wait(boost::bind(print, boost::asio::placeholders::error, t, count));
    


int main()
 
    boost::asio::io_service io;
    int count = 0;
    boost::asio::deadline_timer t(io, boost::posix_time::seconds(1));

    t.async_wait(boost::bind(print, boost::asio::placeholders::error, &t, &count));

    io.run();
    std::cout << "Final count is " << count << std::endl;

    return 0;


它做了它应该做的事:数到五。希望对某人有所帮助。

【讨论】:

【参考方案5】:

封装此功能的 Boost Asio 附加类(每 N 毫秒调用一次指定函数):https://github.com/mikehaben69/boost/tree/main/asio

repo 包含一个演示源文件和 makefile。

【讨论】:

以上是关于C++ Boost ASIO 简单的周期性定时器?的主要内容,如果未能解决你的问题,请参考以下文章

C++ Boost Asio 简单聊天教程

C++ boost::asio::io_service创建线程池thread_group简单实例

C++ boost::asio::io_service创建线程池thread_group简单实例

Boost.Asio的使用技巧

boost asio 学习 定时器

从 boost::threads 到 boost::asio 定时器