日期:2014-05-16  浏览次数:20666 次

(莱昂氏unix源代码分析导读-19)再谈进程swtch

我们已经涉及到了部分进程切换的概念,在本章中,我们会从更一般的意义上考察进程切换的行为。

首先,进程切换(也称作context switch)一定是在内核中完成的。


比如,以下为发生进程切换的最常见的情况:

(1)    active进程因等待某资源阻塞,自动让出cpu;

(2) 进程时间片用完;

 

情况1中,进程会通过系统调用进入内核,在内核态让出cpu;

而情况2的检查是在时钟中断处理程序中进行的。

 

就其原因来讲,进程switch分为两种情况:

(1) 自愿的进程切换,如上述第一种情形;

(2) 非自愿的进程切换,如除上述第二种情形。

 

本章主要讨论的是自愿进程切换。另外,进程管理中涉及了大量中断、信号(软中断)、换入

换出(swap)相关的内容,本章对这部分内容或者跳过,或者一笔带过,对它们的详细讲解

会在自己的专题中完成。

 

首先,看一看swtch()函数。从上一章中已经知道,进程的切换是在swtch()中完成的,Swtch()可分为3段,

每段分属一个进程:

 

2178: swtch()

2179: {

          ……

2189:     savu(u.u_rsav);                          /#进程 M,保存自己

2190:     /*

2191:      * Switch to scheduler's stack

2192:      */

2193:      retu(proc[0].p_addr);              /切换到#0进程

           ……

2200:      /*

2201:      * Search for highest-priority runnable process

2202:      */

          ……                                                /寻找最高优先级的进程N

2215: /*

2216: * If no process is runnable, idle.

2217: */

2218:     if(p == NULL) {                       /如没有可用进程,则idle

2219:         p = rp;             

2220:         idle();                                    /idle函数的核心是wait指令,陷入idle状态

2221:         goto loop;                             /显然,系统idle时,“active”进程为#0进程

2222:      }    

2223:      rp = p;

2224:      curpri = n;

2225:       /* Switch to stack of the new process and set up

2226:       * his segmentation registers.

2227:       */

2228:       retu(rp->p_addr);                   /切换kisa6,即切换到#N进程

2229:       sureg();                                   /这个函数大家应该比较熟悉了,它用来设置新进程的user态寄存器

                 ……