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

What could be delaying my select() call?

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

为了获得一定程度的 "soft" 实时保证,此线程 运行 具有最高优先级 SCHED_FIFO(在 [=19 中显示为 "RT" =]).它是系统中唯一 运行 具有此优先级的线程,没有其他进程具有这样的优先级。我的进程有另一个 SCHED_FIFO 优先级较低的线程,而其他所有线程都在 SCHED_OTHER。两个 "real-time" 线程没有 CPU 绑定,除了等待 I/O 和传递数据外几乎没有做任何事情。

我使用的内核没有 RT_PREEMPT 补丁(我以后可能会切换到那个补丁)。我知道如果我想要 "proper" 实时,我需要切换到 RT_PREEMPT 或者,更好的是,Xenomai 或类似的。但尽管如此,我还是想知道 "vanilla" 内核上以下时序异常背后的原因:

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

提出这个问题的另一种方式是,在不切换到"harder"实时环境的情况下,我还能做些什么来减少这些延迟异常?

更新:我观察到一个新的 "worse worst case" 大约 118.4 毫秒(一次超过总共约 2500 万次 select() 调用)。即使我没有使用带有任何实时扩展的内核,我还是有点担心最后期限显然会错过十分之一秒以上。

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

  1. 中断和由中断触发的代码在内核中占用太多时间,以至于您的实时线程明显延迟。这取决于中断的频率,涉及哪些中断处理程序等
  2. 具有较低优先级的线程不会在内核中被中断,直到它产生 cpu 或离开内核。
  3. 正如 this SO answer 中所指出的,CPU 系统管理中断和热管理也会导致显着的时间延迟(发帖者观察到长达 300 毫秒)。

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

如果

sched_rt_period_ussched_rt_period_us 设置为合理的值并且您的代码的行为符合您的预期,则它们应该不是问题。尽管如此,我还是会取消 RT 线程的限制,看看会发生什么。

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