写在前面:
- 本系列笔记主要以《计算机操作系统(汤小丹…)》为参考,大部分内容出于此书,笔者的工作主要是挑其重点展示,另外配合下方视频链接的教程展开思路,在笔记中一些比较难懂的地方加以自己的一点点理解(重点基本都会有标注,没有任何标注的难懂文字应该是笔者因为强迫症而加进来的,可选择性地忽略)。
- 视频链接:操作系统(汤小丹等第四版)_哔哩哔哩_bilibili
一、概述
进程控制是进程管理中最基本的功能,主要包括创建新进程、终止已完成的进程、将因发生异常情况而无法继续运行的进程置于阻塞状态、负责进程运行中的状态转换等功能。
进程控制一般是由OS的内核中的原语实现的,原语是由若干条指令组成、能够完成一定功能的程序段,算是一种特殊的程序,其执行必须一气呵成,这个需要用关/开中断实现(进入原语程序后关闭中断,让它的所有动作不可分割地进行完,再打开中断)。
原语处于操作系统最底层,是最接近硬件的部分,其运行时间较短,且调用频繁。
二、操作系统内核
1、概述
现代操作系统一般将OS划分为若干层次,再将OS的不同功能分别设置在不同的层次中。通常将一些与硬件紧密相关的模块(如中断处理程序等)、各种常用设备的驱动程序以及运行频率较高的模块(如时钟管理、进程调度和许多模块所公用的一些基本操作)都安排在紧靠硬件的软件层次中,将它们常驻内存,即通常被称为的OS内核,其指令操作工作在核心态。
2、处理机的两种执行状态
计算机系统中,通常CPU执行两种不同性质的程序,一种是操作系统内核程序,另一种是用户自编程序或系统外层的应用程序。对操作系统而言,这两种程序的作用不同,前者是后者的管理者,因此“管理程序”要执行一些特权指令,而“被管理程序”出于安全考虑不能执行这些指令。
操作系统在具体实现上划分了用户态和核心态,以严格区分两类程序。
①系统态:又称为管态,也称为内核态、核心态,它具有较高的特权,能执行一切指令,访问所有寄存器和存储区,传统的OS都在系统态运行。
②用户态:又称为目态,它具有较低的特权,仅能执行规定的指令,访问指定的寄存器和存储区。一般情况下,系统外层的应用程序只能在用户态运行,不能去执行OS指令及访问OS区域,这样可以防止应用程序对OS的破坏。
用户态和核心态的转换:
①“用户态→核心态”是通过中断实现的,并且中断是唯一途径。当中断发生后,当前运行的进程暂停运行,由操作系统内核对中断进行处理,由于操作系统的管理工作(比如进程切换、分配I/O设备等)需要使用特权指令,因此CPU要从用户态转为核心态。
②“核心态→用户态”是通过执行一个特权指令实现的,它可将程序状态字(PSW)的标志位设置为“用户态”。
系统调用发生在用户态,而系统调用的相关处理涉及到对系统资源的管理、对进程的控制,这些功能需要执行一些特权指令才能完成,因此系统调用的相关处理需要在核心态下进行,也就是说,系统调用会使处理器从用户态进入核心态。
系统调用背后的过程是:传递系统调用参数→执行陷入指令(内中断)→执行系统调用相应服务程序→返回用户程序。
①陷入指令是在用户态执行的,执行陷入指令之后立即引发一个内中断,CPU进入核心态。(也就是说,陷入指令可以使用户态转换为核心态)
②发出系统调用请求是在用户态,而对系统调用的相应处理是在核心态下进行的。
③陷入指令是唯一一个只能在用户态执行、而不可在核心态执行的指令。
3、OS内核的功能
(1)支撑功能:
①中断处理。中断处理是内核最基本的功能,是整个操作系统赖以活动的基础,OS中许多重要的活动,如各种类型的系统调用、键盘命令的输入、进程调度、设备驱动等,无不依赖于中断。中断机制中只有一小部分功能属于内核,这部分负责保护和恢复中断现场的信息,转移控制权到相关的处理程序,这样可以减少中断的处理时间,提高系统的并行处理能力。
②时钟管理。在计算机的各种部件中,时钟是最关键的设备,时钟的第一功能是计时,操作系统需要通过时钟管理,向用户提供标准的系统时间;另外,通过时钟中断的管理,可以实现进程的切换,如在分时操作系统中采用时间片轮转调度的实现、在实时系统中按截止时间控制运行的实现、在批处理系统中通过时钟管理来衡量一个作业的运行程度等,因此,系统管理的方方面无不依赖于时钟。
③原语操作。原语在执行过程中不允许被中断,原语相应的原子操作在系统态下执行。
(2)资源管理功能:
①进程管理。在进程管理中,或者由于各个功能模块的运行频率较高(如进程的调度与分派、进程的创建与撤消等),或者由于它们为多种功能模块所需要(如用于实现进程同步的原语、常用的进程通信原语等),通常都将它们放在内核中,以提高OS的性能。
②存储器管理。存储器管理软件的运行频率也比较高,如用于实现将用户空间的逻辑地址变换为内存空间的物理地址的地址转换机构、内存分配与回收的功能模块以及实现内存保护和对换功能的模块等,通常也将它们放在内核中,以保证存储器管理具有较高的运行速度。
③设备管理。由于设备管理与硬件(设备)紧密相关,因此其中很大部分也都设置在内核中,如各类设备的驱动程序、用于缓和CPU与I/O速度不匹配矛盾的缓冲管理、用于实现设备分配和设备独立性功能的模块等。
4、操作系统的体系结构
(1)大内核:将操作系统的主要功能模块都作为系统内核,运行在核心态。
①优点:高性能。
②缺点:内核代码庞大,结构混乱,难以维护。
(2)微内核:仅把最基本的功能保留在内核。
①优点:内核功能少,结构清晰,方便维护。
②缺点:需要频繁地在核心态和用户态之间切换,性能低。
三、进程的创建
1、进程的层次结构
(1)在OS中,允许一个进程创建另一个进程,通常把创建进程的进程称为父进程,而把被创建的进程称为子进程。子进程可继续创建更多的孙进程,由此便形成了一个进程的层次结构。
(2)子进程可以继承父进程所拥有的资源,例如继承父进程打开的文件、继承父进程所分配到的缓冲区等。当子进程被撤消时,应将其从父进程那里获得的资源归还给父进程;在撤消父进程时,也必须同时撤消其所有的子进程。进程不能拒绝其子进程的继承权。
(3)为了标识进程之间的家族关系,在PCB中设置了家族关系表项,以标明自己的父进程及所有的子进程。
2、进程图
所谓进程图就是用于描述进程间关系的一棵有向树,图中的结点代表进程。
如下图所示,在进程D创建了进程I之后,称D是I的父进程,称I是D的子进程,用一条由进程D指向进程I的有向边来描述它们之间的父子关系。创建父进程的进程称为祖先进程,这样便形成了一棵进程树,把树的根结点作为进程家族的祖先。
3、引起创建进程的事件
(1)用户登录。在分时系统中,用户在终端键入登录命令后,若登录成功,系统将为该用户建立一个进程,并把它插入就绪队列中。
(2)作业调度。在多道批处理系统中,当作业调度程序按一定的算法调度到某个(些)作业时,便将它(们)装入内存,为它(们)创建进程,并把它(们)插入就绪队列中。
(3)提供服务。当运行中的用户程序提出某种请求后,系统将专门创建一个进程来提供用户所需要的服务,例如用户程序要求进行文件打印,操作系统将为它创建一个打印进程,这样不仅可使打印进程与该用户进程并发执行,而且还便于计算为完成打印任务所花费的时间。
(4)应用请求。这类事件由用户进程自己创建新进程,以便使新进程以同创建者进程并发运行的方式完成特定任务,例如某用户程序需要不断地先从键盘终端读入数据,继而再对输入数据进行相应的处理,然后再将处理结果以表格形式在屏幕上显示,该应用进程为使这几个操作能并发执行,可以分别建立键盘输入进程、表格输出进程。
4、进程的创建过程
在系统中每当出现了创建新进程的请求后,OS便调用进程创建原语Creat按下述步骤创建一个新进程:
①申请空白PCB,为新进程申请获得唯一的数字标识符,并从PCB 集合中索取空白PCB。若PCB申请失败则创建失败。
②为新进程分配其运行所需的资源,包括各种物理和逻辑资源,这些资源或从操作系统或仅从其父进程获得,新进程对这些资源的需求详情一般也要提前告知操作系统或其父进程。如果资源不足(比如内存空间不够),进程不会创建失败,而是处于“等待状态”(“阻塞状态”)等待资源分配。
③初始化进程控制块(PCB)。PCB的初始化包括:
[1]初始化标识信息,将系统分配的标识符和父进程标识符填入新PCB中。
[2]初始化处理机状态信息,使程序计数器指向程序的入口地址,使栈指针指向栈顶。
[3]初始化处理机控制信息,将进程的状态设置为就绪状态或静止就绪状态,对于优先级,通常是将它设置为最低优先级,除非用户以显式方式提出高优先级要求。
④如果进程就绪队列能够接纳新进程,便将新进程插入就绪队列。
四、进程的终止
1、引起进程终止的事件
(1)正常结束,表示进程的任务已经完成,准备退出运行。在任何系统中,都应有个用于表示进程已经运行完成的指示。
(2)异常结束,是指进程在运行时发生了某种异常事件,使程序无法继续运行。常见的异常事件有:
①越界错:这是指程序所访问的存储区,已越出该进程的区域。
②保护错:指进程试图去访问一个不允许访问的资源或文件,或者以不适当的方式进行访问,例如进程试图去写一个只读文件。
③非法指令:指程序试图去执行一条不存在的指令,出现该错误的原因可能是程序错误地转移到数据区,把数据当成了指令。
④特权指令错:指用户进程试图去执行一条只允许OS执行的指令。
⑤运行超时:指进程的执行时间超过了指定的最大值。
⑥等待超时:指进程等待某事件的时间超过了规定的最大值。
⑦算术运算错:指进程试图去执行一个被禁止的运算,例如除数为0的运算。
⑧I/O故障:这是指在I/O过程中发生了错误等。
(3)外界干预,是指进程应外界的请求而终止运行。这些干预有:
①操作员或操作系统干预:指如果系统中发生了某事件,例如发生了系统死锁,由操作员或操作系统采取终止某些进程的方式使系统从死锁状态中解救出来。
②父进程请求:指当子进程已完成父进程所要求的任务时,父进程可以提出请求结束该子进程。
③因父进程终止:指当父进程终止时,它的所有子进程也都应当结束。
2、进程的终止过程
如果系统中发生了要求终止进程的某事件,OS便调用进程终止原语,按下述过程去终止指定的进程:
①根据被终止进程的标识符,从PCB集合中检索出该进程的PCB,从中读出该进程的状态。
②若被终止进程正处于执行状态,应立即终止该进程的执行,并置调度标志为真,用于指示该进程被终止后应重新进行调度。
③若该进程还有子孙进程,还应将其所有子孙进程也都予以终止,以防它们成为不可控的进程。
④将被终止进程所拥有的全部资源或者归还给其父进程,或者归还给系统。
⑤将被终止进程(PCB)从所在队列(或链表)中移出,等待其它程序来搜集信息。
五、进程的阻塞与唤醒
1、引起进程阻塞的事件
(1)向系统请求共享资源失败。进程在向系统请求共享资源时,由于系统已无足够的资源分配给它,此时进程因不能继续运行而转变为阻塞状态。
(2)等待某种操作的完成。当进程启动某种操作后,如果该进程必须在该操作完成之后才能继续执行,则应先将该进程阻塞起来,以等待操作完成。
(3)新数据尚未到达。对于相互合作的进程,如果一个进程需要先获得另一进程提供的数据后才能对该数据进行处理,只要其所需数据尚未到达,进程便只有阻塞。
(4)等待新任务的到达。在某些系统中,特别是在网络环境下的OS,往往设置一些特定的系统进程,每当这种进程完成任务后便把自己阻塞起来,等待新任务的到来。
2、进程阻塞的过程
正在执行的进程,如果发生了上述某事件,进程便通过调用阻塞原语block将自己阻塞,可见,阻塞是进程自身的一种主动行为。
①进入block过程后,由于该进程还处于执行状态,所以应先立即停止执行,把进程控制块中的现行状态由“执行”改为阻塞,并将PCB插入阻塞队列,如果系统中设置了因不同事件而阻塞的多个阻塞队列,则应将本进程插入到具有相同事件的阻塞队列。。
②转调度程序进行重新调度,将处理机分配给另一就绪进程,并进行切换,亦即保留被阻塞进程的处理机状态,按新进程的PCB中的处理机状态设置CPU的环境。
3、进程的唤醒过程
当被阻塞进程所期待的事件发生时,比如它所启动的I/O操作已完成,或其所期待的数据已经到达,则由有关进程(比如提供数据的进程)调用唤醒原语wakeup,将等待该事件的进程唤醒。wakeup执行的过程是:
①把被阻塞的进程从等待该事件的阻塞队列中移出,将其PCB中的现行状态由阻塞改为就绪。
②将该PCB插入到就绪队列中。
需要注意的是,block原语和 wakeup 原语是一对作用刚好相反的原语,在使用它们时必须成对使用,即如果在某进程中调用了阻塞原语,则必须在与之相合作的、或其它相关的进程中安排一条相应的唤醒原语,以便能唤醒被阻塞进程,否则阻塞进程将会因不能被唤醒而永久地处于阻塞状态,再无机会继续运行。
六、进程的挂起与激活
1、进程的挂起
当系统中出现了引起进程挂起的事件时,OS将利用挂起原语suspend将指定进程或处于阻塞状态的进程挂起。suspend的执行过程是:检查被挂起进程的状态,若处于活动就绪状态,便将其改为静止就绪;对于活动阻塞状态的进程,则将之改为静止阻塞;若被挂起的进程正在执行,则转向调度程序重新调度。
2、进程的激活
当系统中发生激活进程的事件时,OS将利用激活原语active将指定进程激活。激活原语的执行过程是:先将进程从外存调入内存,检查该进程的现行状态,若是静止就绪,便将之改为活动就绪;若为静止阻塞,便将之改为活动阻塞。
假如采用的是抢占调度策略,则每当有静止就绪进程被激活而插入就绪队列时,便应检查是否要进行重新调度,即由调度程序将被激活的进程与当前进程两者的优先级进行比较,如果被激活进程的优先级低,就不必重新调度,否则立即剥夺当前进程的运行,把处理机分配给刚刚被激活的进程。