我目前正在开发一个用C ++编写的GUI,用于一个必须实时轮询,处理然后显示数据(带图)的程序。
我正在努力解决的部分是代码,它运行在一个单独的线程中,实际上是从一些外部硬件轮询数据然后处理它。我希望以固定的周期(即调用之间的1/20秒)定期调用执行此工作的函数。
我真的不知道是否可能以及如何强制执行必须定期调用该函数的事实,每秒正好调用20次......
在阅读了一些关于实时编程的内容之后,基于我从游戏开发和主游戏循环的概念中学到的东西,我的第一种方法是使用一个循环,根据如何调整执行时间轮询+处理花了很多时间:
while(running){
//Let's assume this function get the time elapsed since
//the program started
int start = get_current_time_millisecond();
//Retrieve the data from the hardware
pollData();
//Process the data retrieved
processData();
//Queue the data wherever it is needed:
//- plotting widget of the GUI
//- recording object
dispatchProcessedData();
int elapsed = get_current_time_millisecond() - start;
int remaining = 50 - elapsed;
if(remaining > 0){
sleep(remaining);
}
}
但这似乎有缺陷,因为如果在一次迭代中经过的时间大于我想要坚持的时间,它可能会导致漂移问题。
这可能来自于计算花费太多时间的事实(我非常怀疑它,但我没有足够的经验来确定,并且分析可以帮助消除这个问题,或者至少确定代码可能花了很多时间),但我也想知道我运行多线程的事实是否会因为线程调度而导致同样的问题(再次,我对多线程很新,我可能完全错了)。
因此,我想问:
(如果我错过了很明显/很容易找到关于这个主题的文档,我道歉)
谢谢!
答案 0 :(得分:3)
除非你有一个外部可靠的中断来源,否则很难强制执行这样的约束。
我相信你在消费者操作系统上最接近的事情是:
至少这是我们为我们的产品所做的,它在400 MHz CPU上以100Hz(10ms)进行轮询。你永远不会完全摆脱这种漂移,但它是非常小的。
答案 1 :(得分:1)
正如@Mark建议的那样,最好的方法是使用实时操作系统。
如果某种“软”RT很好,你应该创建一个具有高优先级的线程(例如在Linux中使用调度类实时FIFO或类似的东西)并设置一个循环计时器,它会唤醒你的线程,例如通过信号量。
此外,将绘图与处理分离是个好主意。