什么可以延迟我的select()调用?

时间:2015-05-20 07:51:13

标签: c linux real-time

我有一个在Linux上运行的小程序(在嵌入式PC上,双核Intel Atom 1.6GHz,Debian 6运行Linux 2.6.32-5),它通过FTDI USB转串口转换器与外部硬件通信(使用ftdi_sio内核模块和/dev/ttyUSB*设备)。基本上,在我的主循环中我运行

  • clock_gettime()使用CLOCK_MONOTONIC
  • select(),超时时间为8毫秒
  • 和以前一样
  • clock_gettime()
  • 输出两个clock_gettime()来电的时差

要获得某种程度的“软”实时保证,此线程将以SCHED_FIFO的最高优先级运行(在top中显示为“RT”)。它是系统中唯一以此优先级运行的线程,没有其他进程具有此类优先级。我的进程有另一个SCHED_FIFO线程,优先级较低,而其他所有线程都在SCHED_OTHER。这两个“实时”线程不受CPU限制,除了等待I / O和传递数据之外几乎没有。

我使用的内核没有RT_PREEMPT补丁(我将来可能会切换到该补丁)。我知道如果我想要“正确”实时,我需要切换到RT_PREEMPT,或者更好的是Xenomai等。但是,我想知道“vanilla”内核的后续时序异常背后的原因:

  • 大约0.03%的select()次呼叫的时间超过10毫秒(请记住,超时时间为8毫秒)。
  • 三个最糟糕的情况(超过1200万次通话)分别为31.7毫秒,46.8毫秒和64.4毫秒。
  • 上述所有情况都发生在彼此的20秒内,我认为一些cron工作可能已经干扰了(虽然系统日志信息很少,除了当时正在执行cron.daily的事实)。

所以,我的问题是:在这种极端情况下,可以参与哪些因素?这只是Linux内核本身可能发生的事情,即我切换到RT_PREEMPT,甚至是非USB接口和Xenomai,以获得更可靠的保证吗? /proc/sys/kernel/sched_rt_runtime_us可能会咬我吗?还有其他因素我可能错过了吗?

提出这个问题的另一种方法是,如果没有切换到“更难”的实时环境,我还能做些什么来减少这些延迟异常?

更新:我观察到一个新的,“最糟糕的情况”,大约118.4毫秒(一次超过总共大约2500万select()次呼叫)。即使我没有使用具有任何实时扩展的内核,我也有点担心截止日期显然会超过十分之一秒。

1 个答案:

答案 0 :(得分:2)

如果没有更多信息,很难指出具体的内容,所以我只是在猜测:

  1. 中断触发的中断和代码在内核中占用了大量时间,导致实时线程显着延迟。这取决于中断的频率,涉及中断处理程序等等。
  2. 优先级较低的线程不会在内核中断,直到它产生cpu或离开内核。
  3. 正如this SO answer所指出的,CPU系统管理中断和热管理也会导致严重的时间延迟(海报上观察到最多300毫秒)。
  4. 对于1.6GHz CPU来说,118ms似乎相当多。但是一个意外锁定cpu一段时间的驱动程序就足够了。如果可以,请尝试禁用某些驱动程序或使用不同的驱动程序/硬件组合。

    sched_rt_period_ussched_rt_period_us如果设置为合理的值并且代码的行为符合您的预期,则不应该成为问题。不过,我会删除RT线程的限制,看看会发生什么。

    你还能做什么?写一个设备驱动程序!这并不困难,中断处理程序比实时线程获得更高的优先级。切换到实时内核可能更容易,但YMMV。