Linux内核功能内部的无限循环'do_select'



我很惊讶Linux内核在"do_select"函数实现中有无限循环。这是正常的做法吗?

此外,我还对Linux内核中如何实现文件更改监控感兴趣?又是无限循环吗?

select.c源代码

这不是一个无限循环;该术语是为根本没有退出条件的循环保留的。此循环的退出条件位于中间:http://lxr.linux.no/#linux+v3.9/fs/select.c#L482这是c中一个非常常见的习惯用法。它被称为"循环半",这里有一个简单的伪代码示例:https://stackoverflow.com/a/10767975/388520这清楚地说明了你为什么要这么做。(这个问题涉及Java,但并不重要;这是一个通用的结构化编程习惯用法。)

我不是内核专家,但这个特定的循环似乎是这样写的,因为内部循环的逻辑需要在调用外部循环最底部的poll_schedule_timeout之前和之后运行。该代码正在检查是否有要返回的事件;如果调用select时已经有事件要返回,则应该立即返回;如果最初没有,那么当poll_schedule_timeout返回时就会有。因此,在正常操作中,外环应循环0.5或1.5次。(在边缘情况下,外循环的循环次数可能会超过这个次数。)我可能选择将内循环拉出到自己的函数,但这可能涉及到传递指向太多局部变量的指针。

这也不是一个旋转循环,我的意思是,CPU不会浪费电来一遍又一遍地检查事件,直到发生为止。如果当控制到达对CCD_ 4的呼叫时没有要报告的事件,该函数(最终通过调用__schedule)将导致调用线程阻塞——CPU被从该线程中拿走,并分配给另一个可以用它做一些有用的事情的进程,调用CCD_ 6的线程将被"唤醒"并且CCD_。

更重要的是,操作系统内核经常做一些被认为奇怪、风格差甚至完全错误的事情,为其他工程目标服务(效率、代码重用、避免仅在某些CPU上发生的竞争条件等)。它们是由那些完全了解他们在做什么以及可以在多大程度上绕过规则的人编写的。通过阅读操作系统代码,您可以学到很多东西,但在获得更多经验之前,您可能不应该尝试模仿。你不会试图模仿詹姆斯·乔伊斯的风格作为你创造性写作的第一次练习吧?同样的交易。

最新更新