进程抢占和上下文切换

上下文切换,也就是从一个可运行进程切换到还有一个可运行进程。进程切换schedule函数调用context_switch()函数完毕下面工作:
1.调用定义在<asm/mmu_context.h>中的switch_mm(),该函数负责把虚拟内存从上一个进程映射切换到新进程中。
2.调用定义在<asm/system.h>中的switch_to(),该函数负责从上一个进程的处理器状态切换到新进程的处理器状态。这包含保存、恢复栈信息和寄存器信息。
前面看到schedule函数调用有非常多种情况,全然依靠用户来调用不能达到非常好的效果。内核须要推断什么时候调用schedule,内核提供了一个need_resched标志来表明是否须要又一次运行一次调度:
1当某个进程耗尽它的时间片时,scheduler_tick()就会设置这个标志;
2当一个优先级高的进程进入可运行状态的时候,try_to_wake_up()也会设置这个标志。
每一个进程都包括一个need_resched标志,这是由于訪问进程描写叙述符内的数值要比訪问一个全局变量快
用户抢占
内核即将返回用户空间时候,假设need_resched标志被设置,会导致schedule函数被调用,此时发生用户抢占。
用户抢占在下面情况时产生:
1.从系统调返回用户空间。
2.从中断处理程序返回用户空间。
内核抢占
仅仅要又一次调度是安全的,那么内核就能够在不论什么时间抢占正在运行的任务。
什么时候又一次调度才是安全的呢?仅仅要没有持有锁,内核就能够进行抢占。
锁是非抢占区域的标志。因为内核是支持SMP的,所以,假设没有持有锁,那么正在运行的代码就是可又一次导入的,也就是能够抢占的。
内核抢占会发生在:
1.当从中断处理程序正在运行,且返回内核空间之前。
2.当内核代码再一次具有可抢占性的时候。
3.假设内核中的任务显式的调用schedule()。
4.假设内核中的任务堵塞(这相同也会导致调用schedule())。

猜你喜欢

转载自blog.csdn.net/weixin_43700671/article/details/88992719