内核抢占、用户抢占

时间:2021-04-07 20:14:34

CPU抢占分两种情况:用户抢占、内核抢占。

其中内核抢占是在Linux2.5.4版本发布时加入,同SMP(Symmetrical Multi-Processing,对称多处理器),作为内核的可选配置。

 

1、用户抢占:

        从内核即将返回到用户空间的时候,检查need resched标志,如果被设置,则调用schedule(),此时会发生用户抢占。如果当前进程被抢占,内核会选择一个其它进程运行。

 

2、内核抢占:

       一个在内核态运行的进程,可能在执行内核函数期间被另一个进程取代。

 2.1、内核抢占发生的时机,一般发生在:

       1)当从中断处理程序正在执行,且返回内核空间之前。

       2)当内核代码再一次具有可抢占性的时候,如解锁(spin_unlock_bh)及使能软中断(local_bh_enable)等。

       3)如果内核中的任务显式的调用schedule()。

       4)如果内核中的任务阻塞(这同样也会导致调用schedule())。

 

 2.2、内核抢占,并不是在任何一个地方都可以发生,以下情况不能发生

       1)内核正进行中断处理。在Linux内核中进程不能抢*断(中断只能被其他中断中止、抢占,进程不能中止、抢*断),在中断例程中不允许进行进程调度。进程调度函数schedule()会对此作出判断,如果是在中断中调用,会打印出错信息。

       2)内核正在进行中断上下文的Bottom Half(中断下半部,即软中断)处理。硬件中断返回前会执行软中断,此时仍然处于中断上下文中。如果此时正在执行其它软中断,则不再执行该软中断。

       3)内核的代码段正持有spinlock自旋锁、writelock/readlock读写锁等锁,处干这些锁的保护状态中。内核中的这些锁是为了在SMP系统中短时间内保证不同CPU上运行的进程并发执行的正确性。当持有这些锁时,内核不应该被抢占。

       4)内核正在执行调度程序Scheduler。抢占的原因就是为了进行新的调度,没有理由将调度程序抢占掉再运行调度程序。

       5)内核正在对每个CPU“私有”的数据结构操作(Per-CPU date structures)。在SMP中,对于per-CPU数据结构未用spinlocks保护,因为这些数据结构隐含地被保护了(不同的CPU有不一样的per-CPU数据,其他CPU上运行的进程不会用到另一个CPU的per-CPU数据)。但是如果允许抢占,但一个进程被抢占后重新调度,有可能调度到其他的CPU上去,这时定义的Per-CPU变量就会有问题,这时应禁抢占。

 

 2.3、内核抢占主要是为实时系统来设计的,但也不是在所有情况下都是最优的,因为抢占也需要调度和同步开销,在某些情况下甚至要关闭内核抢占。