内核抢占

本文探讨了Linux内核中的抢占概念,特别是在Linux 2.6内核中,内核抢占如何减少用户态进程的分派延迟。当内核在执行异常处理或系统调用时,如果抢占开启,高优先级进程可以中断当前进程执行。文章还介绍了何时需要同步,如处理竞争条件和临界区,并提到了不同同步技术的应用。
摘要由CSDN通过智能技术生成

为了更好地理解内核代码是如何执行的,我们借用ULK-3中的思想,把内核看作必须满足两种请求的侍者:一种请求来自顾客,另一种请求来自数量有限的几个不同的老板。对不同的请求,侍者采用如下的策略:

1. 老板提出请求时,如果侍者正空闲,则侍者开始为老板服务,这是空闲情况。

2. 如果老板提出请求时侍者正在为顾客服务,那么侍者停止为顾客服务,开始为老板服务,这是高优先级抢占低优先级情况。

3. 如果一个老板提出请求时侍者正在为另一个老板服务,那么侍者停止为第一个老板提供服务,而开始为第二个老板服务,服务完毕再继续为第一个老板服务,这是同优先级情况。

4. 一个老板可能命令侍者停止正在为顾客提供的服务。侍者在完成对老板最近请求的服务之后,可能会暂时不理会原来的顾客而去为新选中的顾客服务。

千万要注意,侍者提供的服务只是针对CPU处于内核态时所执行的代码。如果CPU在用户态执行,则侍者被认为处于空闲状态。

老板的请求相当于中断,而顾客的请求相当于用户态进程发出的系统调用或系统产生的异常。正如我们将在中断专题详细描述的,请求内核服务的用户态进程必须发出适当的指令(在80x86上是int $0x80 或 sysenter指令)。这些指令引起一个异常,它迫使CPU从用户态切换到内核态(如何切换我们在预备知识里讲得很清楚)。

细心的读者已经把前三条原则和中断专题博文“中断和异常处理程序的嵌套执行....... ”所描述的内核控制路径的嵌套联系起来了。但是,第四条原则我第一次看到的时候很茫然,看了半天看不懂,不明白为什么用户态发出系统调用,或系统产生的异常在中断完成后却可以又被新的系统调用或异常所取代。

要理解这个思想,我们必须先学习一个Linux 2.6内核中最有趣的新特点,即内核抢占(kernel preemption)。

1 内核抢占


内核抢占是Linux 2.6中一个重要的概念。我们说:如果进程正执行内核函数时,即它在内核态运行时,允许发生内核切换(被替换的进程是正执行内核函数的进程 ),这个内核就是抢占的。遗憾的是,在Linux中(在所有其他的操作系统中也一样),情况要复杂得多:

第一:无论在抢占内核还是非抢占内核中,运行在内核态的进程都可以自动放弃CPU,比如,其原因可能是,进程由于等待资源而不得不转入睡眠状态。ULK-3中把这种进程切换称为计划性进程切换。但是,抢占式内核在响应引起进程切换的异步事件(例如唤醒高优先权进程的中断处理程序)的方式上与非抢占的内核是有差别的,我们将把这种进程切换称做强制性进程切换。

第二:所有的进程切换都由宏switch_to所代表的汇编代码段来完成,这一点在进程管理专题也描述得很清楚。在抢占内核和非抢占内核中,当进程执行完某些具有内核功能的线程,而且调度程序被调用后,就发生进程切换。不过,在非抢占内核中,当前进程是不可能被替换的,除非它打算切换到用户态,即从系统调用或中断中返回。

所以,抢占内核的主要特点是:一个在内核态运行的进程,当且仅当在执行内核函数期间被另外一个进程取代。

如果还没看明白,让我们举一对实例来说明抢占内核和非抢占内核的区别:进程A执行异常处理程序时(肯定是在内核态),一个具有较高优先级的进程变为可执行状态。这种情况是可能出现的,因为,有可能某个设备,如键盘发生了中断请求而且相应的处理程序唤醒了进程B。如果内核是抢占的,就会发生强制性进程切换,让进程B取代进程A。异常处理程序的执行被暂停,直到调度程序再次选择进程A时才恢复它的执行(B进程执行完毕后不一定马上恢复到A,要看调度程序的选择,这就是前边提到的第四种情况我们所产生的疑问的答案)。相反,如果内核是非抢占的,在进程A完成异常处理程序的执行之前是不会发生进程切换的,除非进程A回到用户态,或者自动放弃CPU。

再看另外一个例子,我们考虑一个执行异常处理程序的进程已经用完了它的时间配额(参见“sch

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值