Linux线程睡眠vs读取

时间:2014-05-20 08:46:15

标签: linux multithreading select scheduler usleep

在我的应用程序中,有一个Linux线程需要每10 ms激活一次, 因此我使用usleep(10 * 1000)。结果:线程在10 ms后永远不会唤醒,但总是在20 ms后唤醒。好的,它与调度程序时间片,CONFIG_HZ等有关。 我试图使用usleep(1 * 1000)(即1 ms)但结果是一样的。线程总是在20 ms后唤醒。

但是在同一个应用程序中,另一个线程处理每10毫秒发出一次的网络事件(UDP数据包)。有阻止' recvfrom' (或'选择')当有传入数据包时,它每10毫秒唤醒一次。 为什么会这样? select必须将线程放入' sleep'什么时候没有包?为什么它的行为不同?如何在没有外部网络事件的情况下每隔10毫秒(或多或少)使我的线程活动?

谢谢, 拉菲

1 个答案:

答案 0 :(得分:3)

你似乎普遍认为这些现代先发制人的多任务都是关于时间和量子的。

他们不是。

它们都是关于软件和硬件中断的,而定时器硬件中断只是可以设置线程就绪并更改正在运行的线程集的众多中断之一。来自NIC的硬件中断导致网络驱动程序运行,这是另一个例子。

如果一个线程被阻塞,等待UDP数据报,并且由于运行驱动程序的NIC中断而导致数据报变得可用,一旦NIC驱动程序运行,阻塞的线程就会准备就绪,因为驱动程序将发出线程信号并在退出时要求立即重新安排。如果您的盒子没有使用更高级别的就绪线程超载,它将被设置为“立即”运行以处理现在可用的数据报。这种机制提供高性能I / O,与任何定时器无关。

定时器中断定期运行以支持sleep()和其他系统调用超时。它以相当低的频率/高间隔运行(如1 / 10ms),因为它是另一个应该最小化的开销。以更高的频率运行这样的中断将减少计时器粒度,但代价是增加的中断状态和重新调度开销,这在大多数桌面安装中是不合理的。

总结:您的计时器操作的粒度为10毫秒,但您的数据报I / O响应很快。

另外,为什么你的线程需要每隔10ms激活一次?你在追究什么?