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

30
我希望有一个非常简单的间期计时器,每50毫秒调用我的代码。我可以创建一个一直睡眠50毫秒的线程(但这很麻烦)... 我可以开始查找Linux API来制作定时器(但这不是可移植的)...
我想使用boost... 我只是不确定是否可能。Boost提供此功能吗?
5个回答

33

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

#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 我不这么认为,但如果你担心这个问题,你可以使用稳定的计时器,它不会受到系统时间更改的影响。在这里看一下:http://www.boost.org/doc/libs/1_65_1/doc/html/boost_asio/reference/steady_timer.html。将我的上面的示例移植到它上面应该很容易。 - Lucio Paiva
2
请注意,boost::asio::io_service::run()会阻塞线程执行,因此您不能在调用它后执行指令并期望定时器同时触发。 - pandaman1234
为什么可以不使用“()”调用tick,即应该是timer.async_wait(tick())? - jaxkewl
1
@jaxkewl 的原因是 tick 没有立即被调用。相反,它的引用被传递给了 async_wait(),后者将在未来调用它。 - Lucio Paiva
+1. expires_at比官方示例中使用的expires_after更准确得多。expires_after会在计时器周期中引入偏差,并在高速率下变得几乎无用。 - rustyx

21
Boost的Asio教程中第二个示例进行了解释。
您可以在这里找到它。

在那之后,检查第三个示例,以了解如何使用周期性时间间隔再次调用它。


请注意,boost::asio::io_service::run()会阻塞线程执行,因此您不能在调用它后执行指令并期望定时器同时触发。 - pandaman1234
等等,如果IO.run阻塞线程执行,那么这个异步的意义是什么? - Jake Gaston

1

为了进一步扩展这个简单的例子。如评论所述,它会阻止执行,因此如果您想要更多的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();

0

0

由于之前的答案存在一些问题,这里提供我的示例:

#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;

}

它做了它应该做的事情:计数到五。希望它能帮助到某些人。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接