4

I'm currently developing a GUI in C++ for a program that must poll, process and then display data (with a plot) in real time.

The part I'm struggling with is the code, running in a separate thread, that actually polls the data from some external hardware and then process it. I want the function that does this work to be called periodically with a fixed period (i.e. 1/20 second between calls).

I don't really know if it's possible and how to enforce the fact that the function must be called periodically, exactly 20 times per second...

After reading a bit about real-time programming, and based on what I learned notably with game development and the concept of the main game loop, my first approach would be to use a loop which would adjust the execution time based on how much time the polling + processing took:

 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);
     }
 }

but this seems flawed, as it may cause a drifting problem, if the time elapsed during one iteration is greater than the period I want to stick to.

This could come from the fact that the computations takes too much time (I highly doubt it, but I'm quite not experienced enough to be sure, and profiling could help eliminate this problem, or at least establish that the code may take to much time), but I also wondered if the fact that I run multiple thread could lead to the same issue due to thread scheduling (again, I'm quite new to multi-threading, I could be completely wrong).

Therefore, I'd like to ask :

  • Is it possible to enforce such a constraint with real-time programming (in a multi-threading context, if relevant) and how ?
  • What are the main guidelines that I should follow when designing this kind of code ?

(I apologize if by any chance I missed obvious/easy to find documentation on this topic)

Thanks !

4

2 回答 2

3

除非你有一个外部的、可靠的中断源,否则很难强制执行这样的约束。

我相信您可以在消费者操作系统上做的最接近的事情是:

  • 确保您使用的是实时内核(例如,使用 Linux 的 RT 补丁)以最大限度地减少时序变化。
  • 将您的轮询线程设置为可能的最高优先级。
  • 仅在您的轮询线程中进行轮询和分派,将任何处理留给较低优先级的线程,以便计算不会影响您的轮询。
  • 使用高精度计时器(在 Linux 上,您可以使用纳秒而不是毫秒)来减少误差范围。
  • 使用无锁队列在轮询线程和处理线程之间进行通信,这样您就不必在轮询线程中支付互斥锁的成本(但每秒只有 20 个样本,这可能无关紧要)。

至少这就是我们为我们的产品所做的,它在 400 MHz CPU 上以 100Hz (10ms) 的频率进行轮询。你永远不会完全摆脱这种方式的漂移,但它非常小。

于 2013-05-28T15:28:57.943 回答
1

正如@Mark 建议的那样,最好的办法是使用实​​时操作系统。

如果一种“软”RT足够好,你应该创建一个具有高优先级的线程(例如在Linux中使用调度类实时FIFO或类似的东西)并设置一个循环定时器,唤醒你的线程,例如通过信号量。

此外,将绘图与处理分离是一个好主意。

于 2013-05-28T15:29:14.803 回答