【发布时间】:2013-05-28 15:15:31
【问题描述】:
我目前正在为一个必须实时轮询、处理和显示数据(带有绘图)的程序用 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);
}
}
但这似乎有缺陷,因为如果在一次迭代中经过的时间大于我想要坚持的时间,它可能会导致漂移问题。
这可能是因为计算花费了太多时间(我对此深表怀疑,但我的经验不足以确定,分析可以帮助消除这个问题,或者至少确定代码可能需要很多时间),但我也想知道我运行多个线程的事实是否会由于线程调度而导致相同的问题(再次,我对多线程很陌生,我可能完全错了)。
所以我想问一下:
- 是否可以通过实时编程(在多线程上下文中,如果相关)强制实施这样的约束以及如何实施?
- 在设计此类代码时应遵循哪些主要准则?
(如果我错过了关于该主题的明显/容易找到的文档,我深表歉意)
谢谢!
【问题讨论】:
-
如果你想对你的进程进行如此严格的调度,你几乎需要一个实时操作系统。大多数桌面操作系统的调度会更加灵活(尽管您可以鼓励它们按照您的意愿行事)。
-
@MarkB 老实说,我有点害怕。不幸的是,这并不意味着要在 RTOS 上运行。那么,我是否应该简单地放弃并保持这种方式(从而放弃我每秒 20 个数据并让程序“尽其所能”)?
-
您是否可以为此访问 C++11?听起来Chrono 是您所需要的。但也许我没有做对,这个 tldr 是否正确? “创建单独的线程来轮询数据并每秒精确存储/处理 20 次”
-
@EdwardA 是的,我可以访问 C++11(感谢您指出 Chrono),是的,这个 tl;dr 是准确的。
标签: c++ multithreading real-time