Linux进程调度过程简单分析

原创作品转载请注明出处 + 《Linux内核分析》MOOC课程http://mooc.study.163.com/course/USTC-1000029000

一、关键代码简析

1、schedule( void ),该函数作为第一个入口,功能很少。

2、__schedule(void),这里开始进入调度函数。

3、context_switch(),这里进行进程上下文切换的一些准备工作。

4、switch_to()函数部分,关键的汇编代码,实现进程上下文切换。

 二、GDB调试过程

        笔者的调试过程异常混乱,也不能很好地整理分析,所以就不贴出来了。

        因为CPU根据时钟信号和中断信号不停地进行这进程调度,所以如果跟踪schedule()的运行,真心不是一般的混乱。

 

三、课件摘录

1、进程调度的时机

1)中断处理过程(包括时钟中断、I/O中断、系统调用和异常)中,直接调用schedule(),或者返回用户态时根据need_resched标记调用schedule();

2)内核线程可以直接调用schedule()进行进程切换,也可以在中断处理过程中进行调度,也就是说内核线程作为一类的特殊的进程可以主动调度,也可以被动调度;

3)用户态进程无法实现主动调度,仅能通过陷入内核态后的某个时机点进行调度,即在中断处理过程中进行调度。

 

2、进程切换的一般过程

用户态进程X ---->用户态进程Y(中断上下文的切换+进程上下文切换

1)发生中断

save cs:eip/esp/eflags(current) to kernel stack, then load cs:eip(entry of a specific ISR) and ss:esp(point to kernel stack).

2)保存现场 SAVE_ALL

3)中断处理过程中或中断返回前调用schedule()

4)标号1之后开始运行用户态进程Y

5)恢复现场  restore_all(属于Y进程的操作)

6)iret - pop cs:eip/ss:esp/eflags from kernel stack

7)继续运行用户态进程Y

3、几种特殊情况

1)通过中断处理过程中的调度时机,用户态进程与内核线程之间互相切换和内核线程之间互相切换,与最一般的情况非常类似,只是内核线程运行过程中发生中断没有进程用户态和内核态的转换

2)内核线程主动调用schedule(),只有进程上下文的切换,没有发生中断上下文的切换,与最一般的情况略简略

3)创建子进程的系统调用在子进程中的执行起点及返回用户态,如fork

4)加载一个新的可执行程序后返回到用户态的情况,如execve

发表评论

电子邮件地址不会被公开。 必填项已用*标注