Linux c++ timer周期性回调
linux c++ timer periodic callback
我试图写一个简单的程序,在其主循环调用不同的函数基于用户输入(这里没有问题),并执行自己的一些动作-那些是基于时间的。由于我想避免潜在的数据访问问题(我不擅长多线程),我试图使用回调来确保每隔几毫秒调用程序的各个自治部分。
从我所发现的,boost::asio看起来像要走的路-但是我不知道这里的正确方法是什么。我已经做了一个简单的代码,工作:
#include <iostream>
#include <boost/asio.hpp>//scheduling
#include <boost/date_time/posix_time/posix_time.hpp>
using namespace std;
void clb(const boost::system::error_code&){
// eye.procFrame(&img, true);
cout << "callback ok" << endl;
}
int main() {
bool run = true;
int i =0;
while(run){
boost::asio::io_service io;
boost::asio::deadline_timer t(io, boost::posix_time::seconds(2));
t.async_wait(clb);
io.run();
if(++i>10) run = false;
}
cout << "done, i=" << i;
return 0;
}
我主要关心的是声明——如果我把它们移出while循环,回调只发生一次。是否有一种方法来写回调类似于定时器中断从微控制器?
睡眠不是一个解决方案-它会使程序无响应,并不能保证,程序的部分是根据他们的时间表更新(例如GUI可以每25毫秒更新一次,但图像捕获应该每秒只发生10次[100毫秒周期]作为一个繁重的操作占用大量资源)
也许有一种完全不同的方法会更好?我在考虑更多的线程,但我担心如果我尝试线程化程序的每一部分,我将以一碗意大利面结束,我永远无法长期管理。
如果你想让你的计时器反复触发,你可以在你的计时器回调中调用deadline_timer::expires_from_now
和deadline_timer::async_wait
。这将使计时器在每次触发时重新调度自己。
定时器与io_service
对象相关联,该对象应该在一个或多个线程上运行。您可以将任意数量的计时器与单个io_service
相关联。如果你想让你的定时器串行执行,而不担心并发问题,只需要一个线程运行你的io_service
。
在这个例子中,我有一个线程运行一个io_service和两个计时器。
#include <iostream>
#include <boost/asio.hpp>
#include <boost/chrono.hpp>
boost::asio::io_service io;
boost::asio::deadline_timer timerA(io);
boost::asio::deadline_timer timerB(io);
boost::chrono::steady_clock::time_point appStart;
void onTimerA(const boost::system::error_code& error)
{
assert(!error);
std::cout << "A fired at " <<
boost::chrono::duration_cast<boost::chrono::milliseconds>
(boost::chrono::steady_clock::now() - appStart).count()
<< std::endl;
timerA.expires_from_now(boost::posix_time::seconds(1));
timerA.async_wait(onTimerA);
}
void onTimerB(const boost::system::error_code& error)
{
assert(!error);
std::cout << "B fired at " <<
boost::chrono::duration_cast<boost::chrono::milliseconds>
(boost::chrono::steady_clock::now() - appStart).count()
<< std::endl;
timerB.expires_from_now(boost::posix_time::seconds(2));
timerB.async_wait(onTimerB);
}
int main()
{
// Prevents io.run() from returning.
boost::asio::io_service::work work(io);
appStart = boost::chrono::steady_clock::now();
timerA.expires_from_now(boost::posix_time::seconds(1));
timerA.async_wait(onTimerA);
timerB.expires_from_now(boost::posix_time::seconds(2));
timerB.async_wait(onTimerB);
io.run();
}
然而,使用一个线程的缺点是,如果一个计时器回调需要很长时间来执行,它将阻塞其他应该触发的计时器,直到它完成。如果你知道你的计时器回调不会花费很长时间,那么一个线程就可以了。
例如,如果定时器A的间隔为25毫秒,而定时器B的间隔为50毫秒,那么这两个定时器有时会被安排在同一时间触发。其中一个将先执行,另一个将等待该执行完成,然后自己执行。
如果你希望你的计时器回调需要很长时间,你不能让你的计时器等待其他计时器的回调完成,你需要额外的线程运行你的io_service
。
- 架构决策:返回std::future还是提供回调
- 正在为Xtensa simcall函数编写回调函数
- 如何在C++中使用非静态成员函数作为回调函数
- FLTK:按下哪个按钮 - 将数字传递给按钮的回调 (lambda)
- 在简单示例中,Python3 + ctypes 回调会导致内存泄漏
- 用于在回调中调用解析器的设计模式
- 如何使用C++对象的成员函数作为 C 样式回调?
- Java从C++回调到C++回调
- 如何将成员函数作为回调参数传递给需要"typedef-ed"自由函数指针的函数?
- 从不同的 cpp 调用回调函数会导致bad_function_call
- pcap_handler回调仅在使用 NPCAP v0.9991 时包含空数据包
- 不带轮询的 SDL2 事件回调
- C++存储带有可变参数的回调
- 如何使用 Node-addon-API 实现 node-nan 回调
- 处理影响跨不同线程共享对象的定时回调的最佳方法是什么?
- 访问类C++ C 样式回调
- 处理类内的回调时,必须调用对非静态成员函数的引用
- 如果 C 函数仍然可以间接执行(通过回调函数),那么将它声明为静态函数是否是一种不好的做法?
- 在C++中实现回调
- Linux c++ timer周期性回调