【进程管理】强制性调度

来源:互联网 发布:python argparse 使用 编辑:程序博客网 时间:2024/04/30 03:13

Linux内核进程的强制性调度,也就是非自愿的,被动的,剥夺的调度;主要是由时间引起的,有可能发生在进程从系统空间返回到用户空间的前夕;比如在entry.S中的代码片段ret_with_reschedule中是否调用schedule(),最终取决于当前进程task_struct中的need_resched是否为1;在单CPU的情况下有一下几种条件:

(1)在时钟中断的服务程序中,发现当前进程的运行时间过长了;

(2)当唤醒一个进程的时候,发现被唤醒的进程比当前进程更有资格运行;

(3)一个进程通过系统调用或改变调度政策或礼让时,这种情况视为主动的,自愿的调度,因此这样的系统调用会引起立即调度;


对于上述第一种情况,时钟中断服务程序do_timer_interrupt()中调用do_timer()这个函数,do_timer()调用update_process_times来调整当前进程与时间有关的一些参数,当计数器降到为0时,就将need_resched置为1;


对于上述第二种情况,唤醒一个睡眠中的进程,可使用wake_one_process(),就是把进程的状态设置成TASK_RUNNING,然后将进程挂入到runqueue(可执行队列)中,然后便调用reschedule_idle();在reschedule_idle()中,就是将所唤醒的进程与当前进程的nice值(即权重)作比较,如果所唤醒的进程运行资格更高,就将当前进程need_resched置为1;其中当前进程的取得可能不是真正意义上的当前进程(大部分时间都是),因为在schedule()调用中有一小段时间,我们已设置了新的切换进程,因此使用cpu_curr()来取得此进程;


对于上述第三种情况,系统调用sched_setcheduler()改变进程的调度政策,sched_yield()使运行中的进程为其他进程让路,但并不进入睡眠;

(1)在sched_setcheduler()中,capable()来检查进程是否允许执行某种特定的操作;move_first_runqueue()是将进程移到相同资格进程的最前面;

(2)在sched_yield()中,与上述sched_setcheduler()改变进程的调度政策不同,它并不改变当前进程在可执行进程中相对位置,只有当nr_pending(正在等待运行的进程数量)不为0时,礼让才会有意义;


上述都是通过need_resched置为1,并不是主动调度,到真正调度时,会有一个调度延时,其中第三种情况对时间并不敏感,第一种,是看时间的,但并不时间要求,因为要把给它的时间片给用完;第三种,与唤醒的进程做比较,有时间要求;(注:唤醒进程可以使用进程间通信,还可以通过中断服务函数或bh函数来唤醒一些睡眠的进程);

0 0