【发布时间】:2011-05-15 03:08:12
【问题描述】:
我想要一个非常简单的周期性计时器来每 50 毫秒调用一次我的代码。我可以制作一个一直休眠 50 毫秒的线程(但这很痛苦)...我可以开始研究用于制作计时器的 Linux API(但它不是可移植的)...
我希望喜欢使用 boost.. 我只是不确定这是否可能。 boost 是否提供此功能?
【问题讨论】:
标签: c++ linux boost boost-asio
我想要一个非常简单的周期性计时器来每 50 毫秒调用一次我的代码。我可以制作一个一直休眠 50 毫秒的线程(但这很痛苦)...我可以开始研究用于制作计时器的 Linux API(但它不是可移植的)...
我希望喜欢使用 boost.. 我只是不确定这是否可能。 boost 是否提供此功能?
【问题讨论】:
标签: c++ linux boost boost-asio
一个非常简单但功能齐全的示例:
#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() 设置新的到期时间非常重要,否则计时器将立即触发,因为它的当前到期时间已经到期。
【讨论】:
boost::asio::io_service::run() 会阻塞线程执行,因此您无法在调用它后执行指令并期望计时器也同时触发。
tick 没有被立即调用。相反,它的引用被传递给async_wait(),它最终会在未来调用它。
expires_at 比官方示例使用的expires_after 准确得多。 expires_after 在定时器周期中引入了偏差,在高速率下实际上变得无用。
Boosts Asio 教程的第二个例子解释了它。
你可以找到它here。
之后,check the 3rd example 看看如何以周期性的时间间隔再次调用它
【讨论】:
boost::asio::io_service::run() 会阻塞线程执行,因此您无法在调用它后执行指令并期望计时器也同时触发。
进一步扩展这个简单的例子。它会像 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();
【讨论】:
由于我之前的答案有一些问题,这里是我的例子:
#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;
}
它做了它应该做的事:数到五。希望对某人有所帮助。
【讨论】:
封装此功能的 Boost Asio 附加类(每 N 毫秒调用一次指定函数):https://github.com/mikehaben69/boost/tree/main/asio
repo 包含一个演示源文件和 makefile。
【讨论】: