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

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

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

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

我正在使用的内核没有RT_PREEMPT补丁(我将来可能会切换到该补丁)。 我知道,如果我想要“适当的”实时,我需要切换到RT_PREEMPT,或者更好,Xenomai或类似的。 但是,我想知道在“香草”内核的下列时间exception之后是什么:

  • 所有select()调用的大约0.03%定时超过10毫秒(请记住,超时为8毫秒)。
  • 三个最坏的情况(超过1200万个呼叫)分别为31.7ms,46.8ms和64.4ms。
  • 以上所有情况都是在20秒内发生的,我认为一些cron工作可能会干扰(尽pipe系统日志信息量不足,当时cron.daily正在执行)。

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

另一种解决这个问题的方法是,我还能做些什么来减less这些延迟exception, 而不必切换到“更难”的实时环境?

更新 :我观察到一个约118.4毫秒的新“最糟糕的情况”(一次总计约2500万次select()调用)。 即使我没有使用任何types的实时扩展内核,我也有些担心,截止date可能会在十分之一秒内被忽略。

没有更多的信息,很难指出具体的东西,所以我只是在这里猜测:

  1. 由中断触发的中断和代码在内核中花费了很多时间,导致实时线程显着延迟。 这取决于中断的频率,涉及中断处理程序等等。
  2. 具有较低优先级的线程在内核内不会被中断,直到产生cpu或离开内核为止。
  3. 正如在本答复中指出的那样,CPU系统管理中断和散热管理也会造成严重的时间延迟(海报可以观察到300ms)。

对于1.6GHz的CPU来说,118ms似乎相当多。 但是一个意外锁定CPU一段时间的驱动就足够了。 如果可以,请尝试禁用某些驱动程序或使用不同的驱动程序/硬件组合。

sched_rt_period_ussched_rt_period_us设置为合理的值,并且您的代码按照您的预期sched_rt_period_ussched_rt_period_us应该是个问题。 不过,我会删除RT线程的限制,看看会发生什么。

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