操作系统宗大华人民邮电出版社 处理机管理笔记

179 阅读43分钟

进程

多道程序设计

所谓“程序”,是一个在时间上严格有序的指令集合。 在没有引入“多道程序设计”的概念之前,不去严格区分“程序”和“程序的运行”两者之间的不同。这是因为任何一个程序运行时,都是单独使用系统中的一切资源,如处理机(指它里面的指令计数器、累加器、各种寄存器等)、内存、外部设备以及软件等,没有任何竞争者与它争夺或共享。 单道程序设计环境下,系统具有的特点:

  • 资源的独占性
  • 执行的顺序性
  • 结果的再现性

在多道程序设计环境下,内存中允许有多个程序存在,它们轮流地使用着 CPU。这时,上述的3个特点就荡然无存了。 原来内存中的程序进行输入/输出时,CPU就只能空转,以等待输入/输出操作的完成。现在,当程序A等待输入/输出操作完成时,就可以把空转的CPU分配给内存中的另一个可运行的程序B去使用。这样,CPU在运行程序B,外部设备在为程序A服务 image.png 这就是说,在程序A的执行过程中,夹杂进了程序B的执行,打破了程序执行的顺序性,内存中多个程序的执行过程被交织在一起。从宏观上看,好几个程序都在运行着;而从微观上看,每个时刻CPU只能为一个程序服务,运行着的程序都是走走停停。总之,在多道程序设计环境下,各个程序的执行不再可能完全依照自己的执行次序执行了。 因为是多道程序设计环境,程序A和程序B同时存在于内存中。当然,内存中可能还有其他的程序存在。由于执行的顺序性被打破了,这些程序的执行过程被交织在一起,没有任何规律可循。 多道程序设计特点:

  • 执行的并发性:从宏观上看,同时在内存的多个程序都在执行着,都在按照自己程序规定的步骤向前推进;从微观上看,由于CPU在任何时刻只能执行一个程序,因此这些程序轮流占用CPU,交替地执行着。
  • 相互的制约性:内存既然运行着多个程序,它们又共享系统内的资源,相互之间必然会呈现出各种各样的制约。一种是间接制约关系,比如由于系统中某种资源个数有限,不可能同时满足每个程序的需要,当一种资源已经分配给某个程序使用时,另一个程序就可能申请不到,从而影响了它的执行。一种是直接制约关系,比如两个程序共同配合来完成一项任务,如果一个程序要等另一个程序发来信息后才能运行,那么前一个程序就受制于后一个程序。如果后一个程序没有先于前一个程序运行并发出信息,那么前一个程序就无法运行。
  • 状态的多变性:由于诸多程序在系统中并发执行,它们之间在运行过程中存在着各种各样的制约关系,造成内存中每一个程序的状态总处于不断的变化之中。它们时而获得CPU而处于运行状态;时而由于输入/输出或申请某种资源未得到满足而只好等待。走走停停,停停走走,交替式地向前推进,直至先后抵达各自的终点。

在多道程序设计环境下,“程序”和“程序的运行”有了与单道程序设计环境下截然不同的含义。为了保持程序“是一个在时间上严格有序的指令集合”这个概念的原有含义,又为了能够刻画出多个程序共同运行时呈现出的“执行的并发性”、“相互的制约性”、“状态的多变性”这些特征,在操作系统中,就基于以往的“程序”这个概念,又引入了“进程”这一新的概念。

进程的定义

“进程(Process)”是现代操作系统设计中的一个基本概念,也是一个管理实体。

  • 进程说程序的一次运行活动
  • 进程的运行活动说建立在某个数据集合之上的
  • 进程在获得资源的基础上从事自己的运行活动

进程的定义描述为:所谓“进程”,是指一个程序在给定数据集合上的一次执行过程,是系统进行资源分配和运行调度的独立单位。 在多道程序设计系统中,既运行着操作系统程序,又运行着用户程序,因此整个系统中存在着两类进程,一类是系统进程,另一类是用户进程。操作系统中用于管理系统资源的那些并发程序,形成了一个个系统进程,它们提供系统的服务,分配系统的资源;可以并发执行的用户程序段,形成了一个个用户进程,它们是操作系统的服务对象,是系统资源的实际享用者。可以看出,这是两类不同性质的进程,主要区别如下。

  • 在多道程序设计系统中,既运行着操作系统程序,又运行着用户程序,因此整个系统中存在着两类进程,一类是系统进程,另一类是用户进程。操作系统中用于管理系统资源的那些并发程序,形成了一个个系统进程,它们提供系统的服务,分配系统的资源;可以并发执行的用户程序段,形成了一个个用户进程,它们是操作系统的服务对象,是系统资源的实际享用者。可以看出,这是两类不同性质的进程,主要区别如下。
  • 系统进程直接管理有关的软、硬件资源的活动,用户进程不得插手资源管理。在需要使用某种资源时,必须向系统提出申请,由系统统一调度与分配。
  • 系统进程与用户进程都需要使用系统中的各种资源,它们都是资源分配与运行调度的独立单位,但系统进程的使用级别,应该高于用户进程。也就是说,在双方出现竞争时,系统进程有优先获得资源、优先得以运行的权利。只有这样,才能保证计算机系统高效、有序地工作。

进程的特征

进程是程序的一次执行过程,程序是进程赖以存在的基础,这就是说,进程与程序之间有一种必然的联系,但进程又不等同于程序,它们是两个完全不同的概念。 进程的主要特征以及与程序的区别有:

  1. “进程”是一个动态的概念。进程强调的是程序的一次“执行”过程;程序是一组有序指令的集合,在多道程序设计环境下,它不涉及“执行”,是一个静态的概念。
  2. 不同进程可以执行同一个程序。由进程的定义可知,区分进程的条件一是所执行的程序,二是数据集合。即使多个进程执行同一个程序,只要他们运行在不同的数据集合上,就是不同的进程。
  3. 每一个进程都有自己的生命期。既然进程的本质是程序的一次执行过程,当系统要完成某一项工作时,它就“创建”一个进程,以便执行事先编写好的、完成该工作的那段程序。程序执行完毕,完成预定的任务后,系统就“撤销”这个进程,收回它所占用的资源。一个进程创建后,系统就感知到它的存在;一个进程撤销后,系统就无法再感知到它。于是,从创建到撤销,这个时间段就是一个进程的“生命期”。
  4. 进程之间具有并发性。在一个系统中,同时会存在多个进程。于是与它们对应的多个程序同时在系统中运行,轮流占用CPU和各种资源。这正是多道程序设计的初衷,说明这些进程在系统中并发执行着。
  5. 进程间会相互制约。由于进程是系统中资源分配和运行调度的单位,因此在对资源进行共享和竞争中,必然会相互制约,影响了各自向前推进的速度。

进程的状态及状态变迁

进程的基本状态和状态变迁 进程间由于共同协作和共享资源,导致生命期中的状态不断发生变化。 系统中的进程应该具有5种状态:创建、运行、就绪、阻塞和撤销 image.png 创建状态:一个进程正在初创时期,操作系统还没有把它列入到可执行的进程行列中 就绪状态:一个进程已经具备了运行的条件,只要有机会获得CPU,它就可以投入运行 运行状态:一个进程获得了CPU,正在执行中。若系统中只有一个CPU,那么任何时候系统中最多只有一个进程处于运行状态 阻塞状态:进程正在等待某个事件(比如I/O的完成)的发生。在事件到来之前,即使把CPU分配给这个进程,它也无法运行。阻塞状态有时也被称为“等待状态”。 终止状态:一个进程或正常结束,或因某种原因被强制结束。这时,系统正在为其进行善后处理。 进程从一个状态变到另一个状态,称为进程状态的“变迁”。

  • 创建->就绪:一个进程创建完毕,就可被列入到可执行的进程行列中。
  • 就绪->运行:在需要一个新的进程投入运行时,操作系统就在处于就绪状态的进程里挑选目标,选中者的状态就从就绪变为运行。
  • 运行->就绪:引起一个进程的状态从运行变到就绪,最常见的原因是“超时”。
  • 运行->阻塞:如果一个运行进程必须等待某个事件的发生而暂时无法再运行,它的状态就由运行变为阻塞。
  • 阻塞->就绪:当进程等待的事件发生时,处于阻塞状态的进程就变成了就绪
  • 运行->终止:正在运行的进程完成了自己的工作,或用于其他原因必须异常结束,该进程就会被撤销,由运行状态变为终止状态

处于就绪状态与阻塞状态的进程,虽然都“暂时无法运行”,但两者有着本质上的区别。前者已做好了运行的准备,只要获得CPU就可以投入运行;而后者要等待某事件(比如输入/输出)完成后才能继续运行,即使此时把CPU分配给它,它也无法运行。 对进程状态更细致的划分 一个进程被阻塞,整个进程仍然占据着分配给它使用的内存。这个时候可以将CPU分配去运行别的进程。但由于CPU的处理速度很快,就会出现CPU空闲运转。 CPU空闲运转是对系统资源的一种浪费。若这时内存有空余空间,那么从磁盘调进可投入运行的进程,就能达到提高CPU利用率的目的;若内存没有空余空间,那么从内存调出阻塞的进程,腾出一定的空间,再从磁盘调入可运行进程,也能达到提高CPU利用率的目的。 为了能使用这种磁盘(辅存)与内存之间的交换技术,可以在进程5种状态模型的基础上,增加两种状态,即“就绪/挂起”状态和“阻塞/挂起”状态。 处于这两种状态的进程,都表示它们是在辅存而不是内存。只有通过“激活”,才可以使这些进程的状态变迁为“就绪”或“阻塞”,从而进入内存。 image.png

  • 就绪/挂起状态:进程在辅存。只要被激活,进程就可以调入内存,如果获得CPU,就可以投入运行
  • 阻塞/挂起状态:进程在辅存等待衰减的发生。只要被激活,进程就可以到调入到内存里去等待事件的发生
  • 阻塞->阻塞/挂起:如果当前没有就绪进程可运行,且内存又缺少空闲区域装入新的进程,就可以从内存换出一个阻塞进程到辅存,使其状态成为阻塞/挂起,从而腾出必须的内存区域
  • 阻塞/挂起->就绪/挂起:如果一个处于阻塞/挂起状态的进程所等待的事件发生了,那么它的状态将变迁成为就绪/挂起状态,进程仍在辅存
  • 就绪/挂起->就绪:如果当前没有就绪状态的进程可以调度,操作系统就应该把具有就绪/挂起状态的进程调入内存(激活),让它能够投入运行。
  • 就绪->就绪/挂起:由于就绪状态的进程能够立即投入运行,使用通常尽量不把就绪状态变迁成为就绪/挂起状态,而是倾向于通过把阻塞状态进程变迁成为阻塞/挂起状态,来达到腾出内存空间的目的。但如果通过挂起一个就绪进程来释放内存是唯一可取的方法时,那么这种进程状态的变迁也是可取的。
  • 创建->就绪/挂起及创建->就绪:创建一个新进程时,这个进程的状态可以是就绪的,也可以是就绪/挂起的。为了提高CPU的利用率,创建的进程多了,可能出现内存不够的情况,就可以让一部分进程成为就绪/挂起状态。通过激活调入内存,就可以投入运行。
  • 阻塞/挂起->阻塞:很少出现,因为处于阻塞/挂起的状态的进程,首先是阻塞的,不能运行的,把它调入内存没有任何意义。但有这种情况:一个进程终止了,释放了它占用的内存空间。阻塞/挂起状态的进程中,如果有一个进程比就绪/挂起状态的所有进程的优先级都高,且它所等待的事件即将发生,那么把这个阻塞/挂起进程调入内存比把就绪/挂起进程调入内存更合理
  • 运行->就绪/挂起:一般情况在运行进程超时时,其状态是由运行转换成就绪。在一些特殊情况下,如果有必要可以把这个运行进程的状态转换成就绪/挂起,以达到腾出所占内存空间的目的

进程控制块

进程的3个组成部分

为了管理和控制进程,操作系统在创建每一个进程时,都为其开辟一个专用的存储区,用来随时记录它在系统中的动态特性。当一个进程被撤销时,系统就收回分配给它的这个存储区。通常,这个专用存储区被称为进程控制块(Process Control Block,PCB)。 在计算机系统内部,一个进程要由3个部分组成:程序、数据集合以及PCB image.png (a)表示程序和数据集合存放在一个连续存储区的情形 (b)表示程序和数据集合在不连续存储区的情形 (c)表示同一个程序运行在不同数据集合上时,形成两个进程的情形。

进程控制块的内容

PCB所包含的信息 image.png

  • 标识信息:在创建进程时,系统会为其分配一个唯一的编号,以此作为它的标识。“标识”代表了一个进程的身份,是系统内部区分不同进程的依据。
  • 说明信息:这些信息随时反映进程的情况。其中,“进程状态”是指进程当前所处状态是运行、就绪还是阻塞;“程序存放位置”指出该进程所执行的程序在内存的物理地址;“数据存放位置”指出程序执行时的工作区,用来存放要处理的数据集合以及最终的处理结果。
  • 现场信息:当用于某种原因迫使进程暂时让出处理机时,必须把当前各种现场信息保存在PCB的固定单元中。保存的信息应该有CPU中各个通用寄存器的内容、控制寄存器的内容、软中断时的断点地址等。这样做 当进程再次获得处理机时,才可以把这些信息置入处理机的相应寄存器中,恢复到被中断时的状态,从而保证进程继续正常执行,就像从未被中断过一样。
  • 管理信息:“进程优先数”指出进程使用处理机的紧迫程度,它可以由用户提供或系统设置。在进程生命期间,其优先数可以保持不变,也可以根据情况动态修正。优先数是系统分配处理机的一个重要依据。操作系统总是通过队列来管理处于相同状态的进程,具体地说就是通过PCB中的“队列指针”,把相同状态的进程链接在一起,形成一个个队列。

进程间的切换 是指将CPU的执行从一个进程切换到另一个进程。 操作系统是通过进程 PCB 中的现场保护区来实现进程间的切换的 image.png CPU先执行左边的进程P0 若在运行到点x处时,进程P0的执行被打断。 为了充分利用CPU,必须将CPU分配给别的进程使用,即要进行进程间的切换,让CPU从执行一个进程转而去执行另一个进程。 为此进入操作系统。若现在是要运行进程P1, 就先把当前CPU的运行现场保护到进程P0的PCB里, 然后用进程P1的PCB里的现场信息对CPU进行加载(即恢复进程P1的运行现场)。 这样,CPU就开始运行右边的进程P1了。 等到达点y时,若进程P1的运行被打断, 于是又进入操作系统去做进程间的切换。 若现在是要运行进程 P0, 那么先把当前CPU的运行现场保护到进程P1的PCB里, 然后用进程P0的PCB里的现场信息对CPU进行加载(即恢复进程P0的现场)。 这样,CPU就开始从点x往下运行右边的进程P0了。 进程控制块队列 在多道程序设计环境里,同时会创建多个可并发执行的进程。 当计算机系统只有一个CPU 时,每次只能让一个进程运行,其他的进程或处于就绪状态,或处于阻塞状态。为了对这些进程进行管理,操作系统要做3件事:

  1. 把处于相同状态的进程的PCB,通过各自的队列指针链接在一起,形成一个个队列;
  2. 为每一个队列设立一个队列头指针,它总是指向排在队列之首的进程的PCB;
  3. 排在队尾的进程的PCB,它的“队列指针”项内容应该为“−1”,或一个特殊的符号,以表示这是该队的队尾PCB。

image.png 单CPU系统中,任何时刻系统中都只有一个进程处于运行状态,所以运行队列只能有一个PCB 系统中所有处于就绪状态的进程PCB排成一队,称其为“就绪队列”,一般情况下 就绪队列中会有多个进程的PCB排在里面,形成处理机分配时的候选对象。如果就绪队列里没有PCB存在,则称该队列为空。 所有处于阻塞状态进程的PCB,应该根据阻塞的原因进行排队,每一个都称为一个“阻塞队列”。每个阻塞队列可以有多个进程的PCB

进程的调度与管理

进程调度算法

当系统中有多个进程就绪时,必须决定先执行哪一个,也就是说,必须决定把CPU分配给谁使用。操作系统会使用“进程调度程序”,采用的调度方法称为“进程调度算法” 常用的进程调度算法有先来先服务、时间片轮转、优先数以及多级队列等 线来先服务调度算法 先来先服务调度算法的基本思想是:以到达就绪队列的先后次序为标准来选择占用处理机的进程。一个进程一旦占有处理机,就一直使用下去,直至它正常地结束或因等待某事件的发生而让出处理机。 到达的进程的PCB总是排在就绪队列末尾;调度程序总是把CPU分配给排在就绪队列中的第一个进程使用。 image.png 先来先服务是一种最为简单的调度算法。从次序的角度看,它对在就绪队列中的任何进程不偏不倚,公平。但从周转的角度看,对要求CPU时间短的进程或输入/删除请求频繁的进程来讲,就不公平了。 时间片轮转调度算法 为就绪队列中的每一个进程分配一个称为“时间片”的时间段,它是允许该进程占用CPU的最长时间长度。 在使用完一个时间片后,即使进程还没有运行完毕,也要强迫其释放处理机,让给另一个进程使用。 它自己则返回到就绪队列末尾,排队等待下一次调度的到来。采用这种调度算法时,对就绪队列的管理与先来先服务完全相同。 主要区别是进程每次占用处理机的时间由时间片决定,而不是只要占用处理机就一直运行下去,直到运行完毕,或为等待某一事件的发生而自动放弃。 image.png 时间片轮转调度算法经常用在分时操作系统中,在那里,多个用户通过终端设备与计算机系统进行交互会话。操作系统随时接收用户发来的请求,为其创建进程,进行分时处理。处理完毕后,把结果返回用户,然后撤销相应进程,等待用户下一个请求的到来。 轮转过程中,时间片可以是固定长度的,也可以是可变长度的。 固定时间片轮转的特征是,就绪队列里的所有进程都以相等的速度向前推进。 时间片如果设定得太大,大到一个进程足以完成其全部工作所需要的时间,则此时该算法就退化成为先来先服务了;若时间片设定得太小,则调度程序的执行频率上升,系统耗费在调度上的时间增加,真正用于运行用户程序的时间就减少了。 就绪队列里有n个进程,分配的时间片长为q,那么每个进程在长为t=n×q的时间里,可以获得长为q的CPU时间。 固定时间片轮转的优点是简单。但由于这时只有一个就绪队列,调度的质量并不理想,因此产生了可变时间片轮转的策略。在采用这种轮转策略时,每当新的一轮调度开始,系统就根据就绪队列中已有的进程数,计算出这次的时间片 q 值,然后进行轮转。 优先数调度算法 为系统中的每个进程规定一个优先数,就绪队列中具有最高优先数的进程有优先获得处理机的权利;如果几个进程的优先数相同,则对它们实行先来先服务的调度。 采用这种调度算法时,就绪队列应该按照进程的优先数大小来排列。新到达就绪队列进程的 PCB,应该根据它的优先数插入到队列的适当位置。这样,进行调度时,总是把CPU分配给就绪队列中的第1个进程,因为它在当时肯定是队列中优先数最高者。优先级是由优先数确定的。在操作系统中,常是优先数越小者优先级越大。 确定进程的优先级 从下面几个方面考虑:

  1. 根据进程的类型 比如系统进程完成的任务是提高系统服务,分配系统资源 所以给予较高的优先级,同时可以提高系统的工作效率
  2. 根据进程执行任务的重要性。比如 系统中处理紧急情况的报警进程的重要性比较高,给予较高的优先级,一旦有紧急事件发生,就能立即占用处理机进行处理。
  3. 根据进程程序的性质。一个CPU繁忙的进程,由于需要占用较长的运行时间,影响系统整体效率的发挥,因此只能给予较低的优先级。一个输入/输出繁忙的进程,给予较高的优先级后,就能充分发挥CPU和外部设备之间的并行工作能力
  4. 根据对资源的要求。系统资源有处理机、内存和外部设备等。可按一个进程所需资源的类型和数量,确定它的优先数。比如给予占用CPU时间短或内存容量少的进程以较高的优先数,可提高系统的吞吐量
  5. 根据用户的请求。系统可以根据用户的请求,给予它的作业及相应进程很高的优先级,做“加急”处理

进程的优先级可分为静态和动态两种。 静态指在进程的整个生命期内优先数保持不变,优点是实现简单,但欠灵活。 动态指在进程的整个生命期内可随机修正它的优先级别,以适应系统环境和条件的变化。 多级队列调度算法 多级队列调度算法是时间片调度算法与优先级调度算法的结合。 这种调度算法,系统中将维持多个就绪队列,每个就绪队列具有不同的调度级别,可以获得不同长度的时间片。 image.png 第1级就绪队列中进程的调度级别最高,可获得的时间片最短。第n级就绪队列中进程的调度级别最低,可获得的时间片最长。 具体的调度方法是: 创建一个新进程时,它的PCB将进入第1级就绪队列的末尾。 对于在第1级到第n −1级队列中的进程,如果在分配给它的时间片内完成了全部工作,就撤离系统; 如果在时间片没有用完时提出了输入/输出请求,或要等待某事件发生, 就进入相应的阻塞队列里等待。 在所等待的事件出现时,仍回到原队列末尾,参与下一轮调度(也就是每个队列实行先来先服务调度算法); 如果用完了时间片还没有完成自己的工作,那么只能放弃对CPU的使用,降到低一级队列的末尾,参与那个队列的调度。 对位于最后一个队列里的进程,实行时间片轮转调度算法。 整个系统最先调度1级就绪队列,只有在上一级就绪队列为空时,才去调度下一级队列。 当比运行进程更高级别的队列中到达一个进程(可以肯定,在此之前比运行进程级别高的所有队列为空)时,系统将立即停止当前进程的运行,让它回到自己队列的末尾,转去运行级别高的那个进程。 多级队列调度算法优先照顾输入/输出繁忙的进程。输入/输出繁忙的进程在获得一点CPU时间后,就会提出输入/输出请求,因此它们总是被保持在1、2级等较前面的队列中,总能获得较多的调度机会。对于占用 CPU 繁忙的进程,它们需要较长的 CPU 时间,因此会逐渐地由级别高的队列往下降,以获得更多的CPU时间,它们“沉”得越深,被调度到的机会就越少。而一旦被调度到,就会获得更多的CPU时间。由此可知,多级调度算法采用的是“你要得越多,你就必须等待越久”的原则来分配处理机的。 进程调度程序应该具有以下几个方面的主要功能:

  1. 记录系统中所有进程的有关情况,如:进程的当前状态、优先级等
  2. 确定分配处理机的算法,这是主要工作
  3. 完成处理机的分配,在操作系统中,是进程调度程序实施处理机的具体分配的。
  4. 完成处理机的回收

进程调度程序负责具体的处理机分配,完成进程间的切换工作,因此它的执行频率是相当高的,是一个操作系统的真正核心。 引起进程调度程序的工作的情况:

  1. 一个进程从运行状态变成了阻塞状态
  2. 一个进程从运行状态变成了就绪状态
  3. 一个进程从阻塞状态变成了就绪状态
  4. 一个进程正常运行结束后被撤销

(1)(4)两种情况肯定会引起进程调度程序工作,它将从就绪队列里选择一个进程占用处理机,完成进程间的切换 (2)(3)两种情况可能会引起进程调度,也可能是继续运行原进程,这与系统所采用的调度算法有关。 把处理机分配给进程后,还有一个允许它占用多长时间的问题,具体有两种处理方式,一种是不可剥夺(或不可抢占)方式,另一种是剥夺(或抢占)方式。 所谓“不可剥夺方式”,即只能由占用处理机的进程自己自愿放弃处理机。 所谓“剥夺方式”,即当系统中出现某种条件时,就立即从当前运行进程手中抢夺过处理机,重新进行分配。在进程调度算法中,时间片轮转调度算法属于剥夺方式。当一个进程耗费完分配给它的一个时间片,还没有运行结束时,就强抢下它占用的处理机,让它回到就绪队列的末尾,把处理机分配给就绪队列的首进程使用。 至于进程调度算法中的优先数调度算法,既可以设计成是剥夺方式的,也可以设计成是不可剥夺方式的。如果在有比当前运行进程更高级别的进程抵达就绪队列时,为确保它能得到快速的响应,允许它把处理机抢夺过来,这就是可剥夺方式的优先数调度算法,否则就是不可剥夺方式的优先数调度算法。

进程管理的基本原语

为了对进程进行有效的管理和控制,操作系统要提供若干基本的操作,以便能创建进程、撤销进程、阻塞进程和唤醒进程。这些操作对于操作系统来说是最为基本、最为重要的。为了保证执行时的绝对正确,要求它们以一个整体出现,不可分割。也就是说,一旦启动了它们的程序,就要保证做完,中间不能插入其他程序的执行序列。在操作系统中,把具有这种特性的程序称为“原语”。 为了保证原语操作的不可分割性,通常总是利用屏蔽中断的方法。 在启动它们的程序时,首先关闭中断,然后去做创建、撤销、阻塞或唤醒等工作,完成任务后,再打开中断。 创建进程原语 需要时,可以通过调用创建进程原语建立一个新的进程,调用该原语的进程被称为父进程,创建的新进程被称为子进程。创建进程原语的主要功能有3项。

  1. 我新建进程申请一个进程控制块PCB
  2. 将创建者(即父进程)提供的信息填入PCB中,如程序入口地址、优先级等,系统还要给一个编号,作为标识
  3. 将新建进程设置为就绪状态,并按照所采用的调度算法,把PCB排入就绪队列

image.png 撤销进程原语 一个进程在完成自己的任务之后,应该及时撤销,以便释放占用的系统资源。撤销进程原语的主要功能是收回该进程占用的资源,将该进程的PCB从所在队列里摘下,将PCB所占用的存储区归还给系统。 当创建一个进程时,为它申请一个 PCB;当撤销一个进程时,就收回它的PCB。正是如此,才表明操作系统确实是通过进程的PCB来“感知”一个进程的存在的。 一般是由父进程或更上一级的进程(有时称为祖先进程)通过调用撤销进程原语,来完成对进程的撤销工作。 阻塞进程原语 一个进程通过调用阻塞进程原语,或将自己的状态由运行变为阻塞,或将处于就绪的子孙进程改变为阻塞状态。不能通过调用阻塞进程原语,把别的进程族系里的进程加以阻塞。阻塞进程原语的主要功能是将被阻塞进程的现场信息保存到PCB中,把状态改为阻塞,然后将其PCB排到相应的阻塞队列中。如果被阻塞的是自己,那么调用了该原语后,就应该转到进程调度程序去,以便重新分配处理机。 唤醒进程原语 在等待的事件发生后,就要调用唤醒进程原语,以便把某个等待进程从相应的阻塞队列里解放出来,进入就绪队列,重新参与调度。很显然,唤醒进程原语应该和阻塞进程原语配合使用,否则被阻塞的进程将永远无法解除阻塞。 唤醒进程原语的主要功能是在有关事件的阻塞队列中,寻找到被唤醒进程的 PCB,把它从队列上摘下,将它的状态由阻塞改为就绪,然后插入到就绪队列中排队。

作业调度

用户与操作系统的两种接口

用户是通过操作系统使用计算机的。 在用户编写的程序中,可以使用所谓的“系统调用命令”,获得操作系统提供的各种功能服务,这是操作系统在程序一级给予用户的支持。 用户还可以使用操作系统提供的各种操作命令,通过键盘来控制程序的运行。这是操作系统在作业控制一级给予用户的支持。 这样的两种支持,常被称为是用户与操作系统之间的两个“接口”,前者称为“程序接口”,后者称为“命令接口”。 1.特权指令、管态、目态 在多道程序设计环境下,多个进程共享系统资源。正是由于要实现对资源的“共享”,涉及资源管理的硬指令就不能随便使用。 为了确保只在操作系统范围内使用特权指令,计算机系统让CPU取两种工作状态:管态(管理程序态的简称)和目态(目标程序态的简称)。规定当CPU处于管态时,可以执行包括特权指令在内的一切机器指令;当CPU处于目态时,禁止使用特权指令,只能执行非特权指令。如果在目态下发现取到了一条特权指令,中央处理机就会拒绝执行,发出“非法操作”中断。于是,一方面转交操作系统去处理该事件,另一方面出示“程序中有非法指令”的信息,通知用户进行修改。 CPU是处于管态还是目态,硬件会自动设置与识别。当CPU的控制权移到操作系统时,硬件就把CPU工作的方式设置成管态;当操作系统选择用户程序占用处理机时,CPU的工作方式就会由管态转换成为目态。 2.系统调用命令 在多道程序设计环境下,对资源的管理和使用权都集中在操作系统手里,但用户又要使用资源。因此必须提供一种方式,将用户对资源的使用通知操作系统,以便由操作系统代之完成。这种方式就是利用操作系统提供的多种系统调用命令。 操作系统里预先编制了很多不同功能的子程序。用户可以在自己的程序里调用这些子程序,请求操作系统提供功能服务。这些子程序被称为“系统功能调用”程序,简称“系统调用”。 在用户程序中调用这些系统调用提供的功能,就称为“发系统调用命令”。 系统调用命令的程序属于操作系统,它应该在管态下执行。用户程序只有通过计算机系统提供的“访管”指令,才能实现由目态转为管态、进而调用这些功能程序的目的。 访管指令是一条非特权指令,功能是执行它就会产生一个软中断,促使中央处理机由目态转为管态,进入操作系统,并处理该中断。 利用访管指令的这种功能,编译程序就把源程序中的所有系统调用都转换成访管指令,把具体调用的功能转换成不同的编码。这样,就能使CPU执行访管指令由目态进入管态,再根据编码,转到相应的功能处理程序去执行。 不同的操作系统所提供的系统调用命令,在数量上、使用格式上,以及功能上都会不同,但对系统调用的处理过程则大致如此。 从功能上看,可以把系统调用命令分成5大类:

  1. 关于进程管理和控制
  2. 关于外部设备输入/输出
  3. 关于磁盘文件管理
  4. 过于访问系统信息
  5. 过于存储申请与释放

从形式上看,操作系统提供的系统调用与一般的过程调用(或称子程序调用)相似,但它们有着明显的区别。

  1. 一般的过程调用,调用者与被调用者都运行在相同的CPU状态。但发生系统调用时,发出调用命令的调用者运行在目态,被调用的对象则运行在管态。
  2. 一般的过程调用,是直接通过转移指令转向被调用的程序;但发生系统调用时,只能通过软中断指令提供的一个统一的入口,由目态进入管态,经分析后,才转向相应的命令处理程序。
  3. 一般的过程调用,在被调用者执行完后,就径直返回断点继续执行;但系统调用可能会招致进程状态的变化,从而引起系统重新分配处理机。因此,系统调用处理结束后,不一定是返回调用者断点处继续执行。

3.操作命令 在批处理系统中,用户要事先利用作业控制(命令)语言,书写作业说明书。作业说明书连同程序和数据一起提交给系统,系统按照作业说明书上的信息,控制作业的执行。这是所谓的“脱机命令接口”。 在分时系统与个人计算机中,向用户提供的是所谓的“联机命令接口”。也就是说,操作系统要提供一组操作命令,提供终端处理程序以及命令解释程序。用户通过键盘输入所需要的命令;终端处理程序接收并在显示器上回显命令;一条命令输入完毕后,由命令解释程序对它进行分析,然后执行相应的命令处理程序,完成用户的一次请求。 各种操作系统所提供的联机命令,在数量、功能、格式上都不尽相同。为了能向用户提供多方面的服务,联机命令大致可有以下几种类型:

  1. 系统访问命令:如注册、注销和口令等。主要用于系统识别用户,以保证整个系统的安全
  2. 磁盘操作命令:如磁盘格式化、磁盘拷贝和磁盘比较等
  3. 文件操作命令:如文件的显示、文件拷贝和文件删除等
  4. 目录操作命令:如建立子目录、目录显示和目录删除等
  5. 其他命令:如输入/输出重定向和管道连接等

作业与作业管理

1.作业与作业步 所谓“作业”,是用户要求计算机系统所做的一个计算问题或一次事务处理的完整过程。 用户首先要用程序设计语言编写源程序代码,准备好数据,然后把它们输入到计算机中,完成编译、连接与装配等项工作,产生出可以执行的代码,最后投入运行,取得所需要的结果。 任何一个作业都要经过若干加工步骤之后,才能得到结果。我们称每一个加工步骤为一个“作业步”。 一个作业的各个作业步之间是有联系的。通常,上一个作业步的输出是下一个作业步的输入。下一个作业步能否顺利执行,取决于上一个作业步的结果是否正确。 image.png

  1. 用户编写一个c语言源程序
  2. c编译程序将源程序作为输入进行编译产出以.OBJ为扩展名的目标程序
  3. 连接装配程序以目录程序、系统库函数和包含文件等作为输入,产生一个以.EXE为扩展名的可执行文件

2.作业控制块 在把一个作业提交给系统时,系统也要开辟一个作业控制块(Job Control Block,JCB),以便随时记录作业的信息。 image.png 被系统接纳的作业,在没有投入运行之前,称为后备作业。这些作业存放在辅助存储器中,并由它们的JCB连接在一起,形成所谓的后备作业队列。在后备作业队列中的作业,并不参与对处理机的竞争,但系统是从它们里面挑选对象去参与对处理机的竞争的。 3.作业调度 按照某种规则,从后备作业队列中挑选作业进入内存,参与处理机的竞争,这个过程称为“作业调度”。 完成这项工作的程序,称为“作业调度程序”。 作业调度程序中采用的规则,称为“作业调度算法”。 作业调度也称为高级调度,它将决定允许后备作业队列中的哪些作业进入内存。一个作业被作业调度程序调入内存后,系统就为它创建进程,使它能以进程的形式,去参与对处理机的竞争。 进程调度也称低级调度,它将确定当CPU可用时,把它分配给哪一个就绪进程使用,并且实际完成对CPU的分配。 4.作业的状态与状态的变迁 犹如一个进程有生命期一样,从作业提交给系统,到作业运行完毕被撤销,就是一个作业的生命期。 在这期间,作业随着自己的推进,随着多道程序系统环境的变化,其状态也在发生着变化。它由提交状态变为后备状态,变为运行状态,最后变为完成状态

  1. 提交状态:一个作业进入辅助存储器时,称为“提交状态”。这是作业的一个暂时性状态。这时,作业的信息还没有全部进入系统,系统也没有为它建立作业控制块 JCB,因此根本感知不到它的存在。
  2. 后备状态:该状态也称收容状态。在系统收到一个作业的全部信息后,为它建立起作业控制块JCB,并将JCB排到后备作业队列中。这时,它的状态就成为后备状态,系统可以真实地感知到它的存在,它获得了参与处理机竞争的资格。
  3. 运行状态:位于后备作业队列中的作业,一旦被作业调度程序选中,它就进入内存真正参与对CPU的竞争,从而使它的状态由后备转为运行。在一个作业呈现运行状态时,即由作业调度阶段进入了进程调度阶段。在此期间,从宏观上看,处于“运行”状态的多个作业都在执行之中;从微观上看,它们都在走走停停,各自以独立的、不可预知的速度向前推进。
  4. 完成状态:作业运行结束后,就处于完成状态。它也是一个暂时性状态。此时,为了撤销该作业,系统正在做着收尾工作,收回所占用的各种资源,撤除作业的JCB等。

作业的调度算法

确定作业调度算法时,需要注意的问题:

  1. 公平对待后备作业队列中的每一个作业,避免无故或无限期地延迟一个作业的执行,使各类用户感到满意。
  2. 使进入内存的多个作业,能均衡地使用系统中的资源,避免出现有的资源没有作业使用、有的资源却被多个作业争抢的“忙闲”不均的情形。
  3. 力争在单位时间内为尽可能多的作业提供服务,提高整个系统的吞吐能力。

在批处理系统中,使用作业的“周转时间”来描述系统的吞吐能力。 作业i提交给系统(也就是它成为后备作业队列中的一个成员)的时间为 Si,其完成(也就是用户得到运行结果)的时间为Wi。那么该作业的周转时间Ti为 image.png 对于一批n个作业而言,它们的平均周转时间T为 image.png

“先来先服务”作业调度算法

以作业进入后备作业队列的先后次序,作为作业调度程序挑选作业的依据,这就是先来先服务作业调度算法的基本思想。这就是说,哪个作业在后备作业队列中等待的时间最长,下次调度即是选中者。不过要注意,这是以其资源需求能够得到满足为前提的。如果它所需要的资源暂时无法获得,它就会被推迟选中,因为只有这样才合乎情理。

“短作业优先”作业调度算法

要求每个用户对自己作业所需耗费的CPU时间做一个估计,填写在作业说明书中。作业调度程序工作时,总是从后备作业队列中挑选所需CPU时间最少且资源能够得到满足的作业进入内存投入运行,这就是“短作业优先”作业调度算法的基本思想。

“响应比高者优先”作业调度算法

先来先服务的作业调度算法,重点考虑的是作业在后备作业队列里的等待时间,因此对短作业不利;短作业优先的作业调度算法,重点考虑的是作业所需的CPU时间(当然,这个时间是用户自己估计的),因此对长作业不利。 响应比高者优先”的作业调度算法,试图综合这两方面的因素,以便能更好地满足各种用户的需要。 响应比=(已等待时间)/(所需CPU时间) 该比值的分母是不变的,但随着时间的推移,一个作业的“已等待时间”会不断发生变化。 短作业比较容易获得较高的响应比,这是因为它的分母较小,只要稍加等待,整个比值就会上升。 长作业的分母虽然很大,但随着等待时间的增加,比值也会逐渐上升,从而获得较高的响应比。 照顾到了短作业的利益,也照顾到了长作业的利益,是一种折中的作业调度算法。