3

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

但是在同一个应用程序中,另一个线程处理每 10 毫秒出现一次的网络事件(UDP 数据包)。有阻塞“recvfrom”(或“select”),当有传入数据包时,它每 10 毫秒唤醒一次。为什么会这样?没有数据包时,select是否必须将线程置于“睡眠”状态?为什么它的行为不同,如何在没有外部网络事件的情况下使我的线程每 10 毫秒(或多或少)处于活动状态?

谢谢,拉菲

4

1 回答 1

3

你似乎有一个普遍的印象,即这些现代的抢先式多任务处理程序都是关于时间片和量子的。

他们不是。

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

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

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

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

另外,为什么你的线程需要每 10 毫秒激活一次?你投票是为了什么?

于 2014-05-20T11:19:41.543 回答