日期:2014-05-16 浏览次数:20666 次
我们已经涉及到了部分进程切换的概念,在本章中,我们会从更一般的意义上考察进程切换的行为。
首先,进程切换(也称作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态寄存器
……