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::io_service创建线程池thread_group简单实例