diff --git a/Operate-System/1-process-management.md b/Operate-System/1-process-management.md index ab3bdf1..6e3543c 100644 --- a/Operate-System/1-process-management.md +++ b/Operate-System/1-process-management.md @@ -320,6 +320,15 @@ 指作业与进程的调度算法。 ++ 批处理系统算法: + + FCFS。 + + SJF/SPF/SRTN。 + + HRRN。 ++ 交互式系统算法: + + RR。 + + PS。 + + MFQ。 + #### 算法评价指标 + CPU利用率:CPU忙碌时间占总时间的比例。其中利用率=忙碌时间/总时间。 @@ -381,4 +390,366 @@ P4|5|4|7|12|16 #### 短作业优先 -即 +即SJF算法。 + ++ 算法思想:追求最少的平均等待时间,最少的平均周转时间、最少的平均平均带权周转时间。 ++ 算法规则:最短的作业/进程优先得到服务(所谓“最短”,是指要求服务时间最短)。 ++ 用于作业/进程调度:即可用于作业调度,也可用于进程调度。用于进程调度时称为“短进程优先(SPF, Shortest Process First)算法”。 ++ 优缺点: + + 优点:“最短的”平均等待时间、平均周转时间。 + + 缺点:不公平。对短作业有利,对长作业不利。可能产生饥饿现象。另外,作业/进程的运行时间是由用户提供的,并不一定真实,不一定能做到真正的短作业优先。 ++ 是否可抢占:SJF和SPF是非抢占式的算法。但是也有抢占式的版本―——最短剩余时间优先算法(SRTN, Shortest Remaining Time Next)。 ++ 是否会导致饥饿:会。如果源源不断地有短作业/进程到来,可能使长作业/进程长时间得不到服务,产生“饥饿”现象 +。如果一直得不到服务,则称为“饿死” + +1.如果题目中未特别说明,所提到的“短作业/进程优先算法”默认是非抢占式的。2.很多书上都会说“SJF调度算法的平均等待时间、平均周转时间最少”,严格来说,这个表述是错误的,不严谨的。最短剩余时间优先算法得到的平均等待时间、平均周转时间还要更少。应该加上一个条件“在所有进程同时可运行时,采用SJF调度算法的平均等待时间、平均周转时间最少”,或者说“在所有进程都几乎同时到达时,采用SJF调度算法的平均等待时间、平均周转时间最少”。如果不加上述前提条件,则应该说“抢占式的短作业/进程优先调度算法(最短剩余时间优先, SRNT算法)的平均等待时间、平均周转时间最少”。 +3.虽然严格来说,SJF的平均等待时间、平均周转时间并不一定最少,但相比于其他算法(如FCFS),SJF依然可以获得较少的平均等待时间、平均周转时间。 +4.如果选择题中遇到“SJF算法的平均等待时间、平均周转时间最少”的选项,那最好判断其他选项是不是有很明显的错误,如果没有更合适的选项,那也应该选择该选项。 + +**例题:**各进程到达就绪队列的时间、需要的运行时间如下表所示。使用非抢占式短进程优先调度算法和抢占式短进程优先调度算法,分别计算各进程的等待时间、平均等待时间、周转时间、平均周转时间、带权周转时间、平均带权周转时间。 + +进程|到达时间|运行时间 +:--:|:-----:|:------: +P1|0|7 +P2|2|4 +P3|4|1 +P4|5|4 + +如果使用非抢占式的,因为每次选择当前已经到达且运行时间最短的作业/进程,因为P1第一个到达,所以第一个开始,P1完成时是7,P2P3P4都到达了,所以依次选最短运行时间的开始,所以调度顺序为P1、P3、P2、P4。 + +所以周转时间为7、4、10、11。带权周转时间为1、4、2.5、2.75。等待时间为0、3、6、7。平均周转时间为8。平均带权周转时间为2.56。平均等待时间为4。 + +如果使用抢占式的,若新到达进程剩余时间要比当前运行的进程剩余时间更短,则由新进程抢占处理机。 + +0时P1到达,P1剩余时间为7,所以P1开始运行。2时P2到达,此时P1剩余时间为7-2=5,而P2剩余时间为4-0=4,4<5,所以P2抢占P1处理机。4时P3到达,此时P2剩余时间为4-2=2,而P3剩余时间为1-0=1,所以P3又抢占P2处理机。到5时P4到达,此时P3正好运行完,所以要考虑P1P2P4三个的剩余时间,分别为5、2、4,所以P2抢占处理机运行。7时P2运行完,P4抢占处理机。11时P4运行完,P1抢占处理机。最后16时P1运行完,作业全部结束。 + +所以周转时间为16、5、1、6。带权周转时间为2.28、1.25、1、1.5。等待时间分别为9、1、0、2。平均周转时间为7。平均带权周转时间为1.5。平均等待时间为3。 + +#### 高响应比优先 + +即HRRN算法。 + ++ 算法思想:要综合考虑作业/进程的等待时间和要求服务的时间。 ++ 算法规则:在每次调度时先计算各个作业/进程的响应比,选择响应比最高的作业/进程为其服务。响应比=(等待时间+要求服务时间)/要求服务时间(响应比≥1)。 ++ 用于作业/进程调度:即可用于作业调度,也可用于进程调度。 ++ 是否可抢占:非抢占式的算法。因此只有当前运行的作业/进程主动放弃处理机时,才需要调度,才需要计算响应比。 ++ 优缺点: + + 综合考虑了等待时间和运行时间(要求服务时间)。 + + 等待时间相同时,要求服务时间短的优先(SJF的优点)。 + + 要求服务时间相同时,等待时间长的优先(FCFS的优点)。 + + 对于长作业来说,随着等待时间越来越久,其响应比也会越来越大,从而避免了长作业饥饿的问题。 ++ 是否会导致饥饿:不会。 + +**例题:**各进程到达就绪队列的时间、需要的运行时间如下表所示。使用高响应比优先调度算法,计算各进程的等待时间、平均等待时间、周转时间、平均周转时间、带权周转时间、平均带权周转时间。 + +进程|到达时间|运行时间 +:--:|:-----:|:------: +P1|0|7 +P2|2|4 +P3|4|1 +P4|5|4 + +需要利用公式计算响应比,最重要的是等待时间和运行时间。当0时P1到达,P1运行。7时P1完成主动放弃处理机,此时P2P3P4全部到达了,而响应比分别为(5+4)/4=2.25、(3+1)/1=3、(2+4)/4=1.5,所以选择P3上处理机运行。8时,响应比分别为2.5、1.75,P2运行。12时P4运行。 + +#### 时间片轮转 + +即RR算法。 + ++ 算法思想:公平地、轮流地为各个进程服务,让每个进程在一定时间间隔内都可以得到响应。 ++ 算法规则:按照各进程到达就绪队列的顺序,轮流让各个进程执行一个时间片(如100ms)。若进程未在一个时间片内执行完,则剥夺处理机,将进程重新放到就绪队列队尾重新排队。 ++ 用于作业/进程调度:用于进程调度(只有作业放入内存建立了相应的进程后,才能被分配处理机时间片)。 ++ 是否可抢占:若进程未能在时间片内运行完,将被强行剥夺处理机使用权,因此时间片轮转调度算法属于抢占式的算法。由时钟装置发出时钟中断来通知CPU时间片已到。 ++ 优缺点: + + 优点: + + 公平。 + + 响应快,适用于分时操作系统。 + + 缺点: + + 由于高频率的进程切换,因此有一定开销。 + + 不区分任务的紧急程度。 ++ 是否会导致饥饿:不会。 + ++ 常用于分时操作系统,更注重响应时间,所以不怎么关系周转时间。 ++ 如果时间片太大,每个进程在一个时间片内就可以完完成,则时间片轮转算法会退化为先来先服务算法,增大进程响应时间,所以时间片不能太大。 ++ 如果时间片太小,进程切换会频繁发生,需要保存现场恢复环境,增加时间开销。 ++ 一般设计时间片段时要让切换进程的开销不超过1%。 + +**例题:**各进程到达就绪队列的时间、需要的运行时间如下表所示。使用时间片轮转调度算法,分析时间片大小为2时的进程运行状态。 + +进程|到达时间|运行时间 +:--:|:-----:|:------: +P1|0|7 +P2|2|4 +P3|4|1 +P4|5|4 + +注意:当同一时刻既有时间片用完也有新进程到达时,默认新到达进程先进入队列,时间片用完的进程后进入。 + +若时间片为2: + +当0时,因为只有P1到达就绪队列,所以P1运行一个时间片。 + +当2时,P1时间片运行完,余下5个时间。正好P2到达就绪队列,所以P1处理机被剥夺,重新放到就绪队列尾,让P2运行一个时间片。 + +当4时,P2时间片运行完,余下2个时间。正好P3到达就绪队列加入队尾,此时P1到达队头,所以P2处理机被剥夺,重新放到就绪队列尾,让P1运行一个时间片。 + +当5时,P4到达加入就绪队列。此时就绪队列上有P3、P2、P4。 + +当6时,P1时间片运行完,余下3个时间。此时P3到达队头,所以P1处理机被剥夺,重新放到就绪队尾,让P3运行。 + +当7时,虽然P3时间片没有用完,但是由于P3只需一个单位的时间,所以主动放弃处理机,发生调度,让P2运行一个时间片。 + +当9时,P2正好运行完也用完时间片,P4上处理机。 + +当11时,P4时间片用完,余下2个时间,此时P1到达队头,所以P4处理机被剥夺,重新放到就绪队尾,让P1运行。 + +当13时,P1时间片用完,余下1个时间,此时P4到达队头,所以P1处理机被剥夺,重新放到就绪队尾,让P4运行。 + +当15时,P4正好运行完也用完时间片,P4上处理机。 + +当16时,P1运行完,主动放弃处理机。 + +#### 优先级 + +即PS算法。 + ++ 算法思想:随着计算机的发展,特别是实时操作系统的出现,越来越多的应用场景需要根据任务的紧急程度来决定处理顺序。 ++ 算法规则:调度时选择优先级最高的作业/进程。 ++ 用于作业/进程调度:既可用于作业调度,也可用于进程调度。甚至,还会用于在之后会学习的I/O调度中。 ++ 是否可抢占:抢占式、非抢占式都有。做题时的区别在于: + + 非抢占式只需在进程主动放弃处理机时进行调度即可。 + + 抢占式还需在就绪队列变化时,检查是否会发生抢占。 ++ 优缺点: + + 优点:用优先级区分紧急程度、重要程度,适用于实时操作系统。可灵活地调整对各种作业/进程的偏好程度。 + + 缺点:若源源不断地有高优先级进程到来,则可能导致饥饿。 ++ 是否会导致饥饿:会。 + ++ 优先数与优先级的关系要看具体情况,如Windows优先级与优先数成正比,UNIX中成反比。 ++ 优先级调度算法中就绪队列未必只有一个,可以按照不同优先级来组织。 ++ 可以把优先级更高的进程排在队头位置。 ++ 根据优先级是否可以动态改变,分为: + + 静态优先级:创建进程时确定,一直保持不变 + + 动态优先级:创建进程时有初始值,之后根据情况动态调整优先级。 ++ 设置进程优先级: + + 系统进程高于用户进程。 + + 前台进程高于后台进程。 + + 操作系统更偏好I/O型进程(I/O繁忙型进程)而不是计算型进程(CPU繁忙型进程),I/O设备和CPU可以并行工作。如果优先让I/O繁忙型进程优先运行的话,则越有可能让I/O设备尽早地投入工作,则资源利用率、系统吞吐量都会得到提升。 ++ 调整动态优先级: + + 若进程在就绪队列中等待了很长时间,则提升其优先级。 + + 若进程占用处理机很长时间,则降低其优先级。 + + 若进程频繁进行I/O操作,则提升其优先级。 + +**例题:**各进程到达就绪队列的时间、需要的运行时间、进程优先数如下表所示。使用非抢占式与抢占式优先级调度算法,分析进程运行状态。(优先级越大,优先级越高) + +进程|到达时间|运行时间|优先数 +:--:|:-----:|:------:|:---: +P1|0|7|1 +P2|2|4|2 +P3|4|1|3 +P4|5|4|2 + +非抢占式: + +0时只有P1到达,所以P1开始处理。 + +2时P2到达,4时P3到达,5时P4到达。 + +7时P1运行完,因为P3优先级更高,所以运行P3。 + +8时P3运行完,P2P4优先级相同,但是由于P2先到,所以P2上处理机。 + +12时P2运行完,P4上处理机。 + +16时P4运行完。 + +抢占式: + +0时P1到达,P1上处理机。 + +2时P2到达,且P2优先级2大于P1优先级1,所以P2上处理机,P1余下5。 + +4时P3到达,且P3优先级3大于P2优先级2,所以P3上处理机,P2余下2。 + +5时P3运行结束,且P4到达,插入就绪队列队尾,P2进入队列时间更早,所以P2上处理机。 + +7时P2运行结束,且P4优先级4大于P1优先级1,所以P4上处理机。 + +11时P4运行结束,P1上处理机。 + +16时P1运行结束。 + +#### 多级反馈队列 + +即MFQ算法。 + ++ 算法思想:对其他调度算法的折中权衡。 ++ 算法规则: + 1. 设置多级就绪队列,各级队列优先级从高到低,时间片从小到大。 + 2. 新进程到达时先进入第1级队列,按FCFS原则排队等待被分配时间片,若用完时间片进程还未结束,则进程进入下一级队列队尾如果此时已经是在最下级的队列,则重新放回该队列队尾。 + 3. 只有第k级队列为空时,才会为k+1级队头的进程分配时间片 ++ 用于作业/进程调度:用于进程调度。 ++ 是否可抢占:抢占式的算法。在k级队列的进程运行过程中,若更上级的队列(1~k-1级)中进入了一个新进程,则由于新进程处于优先级更高的队列中,因此新进程会抢占处理机,原来运行的进程放回k级队列队尾。 ++ 优缺点: + + 对各类型进程相对公平(FCFS的优点)。 + + 每个新到达的进程都可以很快就得到响应(RR的优点)。 + + 短进程只用较少的时间就可完成(SPF的优点)。 + + 不必实现估计进程的运行时间(避免用户作假)。 + + 可灵活地调整对各类进程的偏好程度,比如CPU密集型进程、I/O密集型进程(拓展:可以将因I/O而阻塞的进程重新放回原队列,这样I/O型进程就可以保持较高优先级) ++ 是否会导致饥饿:会。 + +**例题:**各进程到达就绪队列的时间、需要的运行时间如下表所示。使用多级反馈队列调度算法,分析进程运行状态。 + +进程|到达时间|运行时间 +:--:|:-----:|:------: +P1|0|7 +P2|2|4 +P3|4|1 +P4|5|4 + +设置多级就绪队列,各级队列优先级从高到低,时间片从小到大。 + +新进程到达时先进入第1级队列,按FCFS原则排队等待被分配时间片。 + +若用完时间片进程还未结束,则进程进入下一级队列队尾。如果此时已经在最下级的队列,则重新放回最下级队列队尾。 + +只有第k级队列为空时,才会为k+1级队头的进程分配时间片。 + +被抢占处理机的进程重新放回原队列队尾。 + +定义多级就绪队列如下(优先级与优先数成正比): + +队列序号|优先级|时间片大小 +:-----:|:----:|:-------: +1|3|1 +2|2|2 +3|1|4 + +0时首先P1进入第一级队列,此时P1优先级为4,时间片为1,所以P1会运行1。 + +1时P1余下6,没有运行完,进入第二级队列的队尾。 + +2时P2进入第一级队列,优先级更高,所以P1被剥夺处理机,此时P1还余下5,回退第二级队列,P2开始运行。 + +3时P2运行一个时间片后余下3,加入第二级队列队尾。此时第二级队列头部为P1,所以P1开始运行。 + +4时P3进入第一级队列,优先级更高,所以P1被剥夺处理机,此时P1还余下4,回退第二级队列。 + +5时P4进入第一级队列,此时P3也正好运行完,处理机交给P4。 + +6时P4运行一个时间片后余下3,加入到第二级队列尾部。第二级队列此时顺序为P2(余3)、P1(余4)、P4(余3),所以P2开始运行。 + +8时P2运行一个时间片后余下1,加入到第三级队列中。P1开始占有处理机。 + +10时P1运行一个时间后余下2,加入到第三级队列中。P4开始占有处理机。 + +12时P4运行一个时间后余下1,加入到第三级队列中。第二级队列为空,开始运行第三级队列,P2开始占有处理机。 + +13时P2处理完,P1占有处理机。 + +15时P1处理完,P4占有处理机。 + +16时P4处理完,全部结束。 + +## 进程同步与互斥 + +### 进程同步与互斥的基本概念 + +#### 进程同步 + ++ 同步也称为直接制约关系。 ++ 在多道程序环境下,进程是并发执行的,不同进程之间存在着不同的相互制约关系。为了协调进程之间的相互制约关系,如等待、传递信息等,引入了进程同步的概念。进程同步是为了解决进程的异步问题。 ++ 异步性:进程具有异步性的特征。指各并发执行的进程以各自独立的、不可预知的速度向前推进。 + +#### 进程互斥 + ++ 互斥也称间接制约关系。 ++ 进程互斥指当一个进程访问某临界资源时,另一个想要访问该临界资源的进程必须等待。当前访问临界资源的进程访问结束,释放该资源之后,另一个进程才能去访问临界资源。 ++ 资源共享方式分为: + + 互斥共享方式:允许多个进程使用,但是同一个时间段内只允许一个进程访问该资源。 + + 同时共享方式:允许一个时间短内由多个进程在宏观上同时对其访问。 + +#### 临界资源 + ++ 我们把一个时间段内只允许一个进程使用的资源称为临界资源。许多物理设备(比如摄像头、打印机)都属于临界资源。此外还有许多变量、数据、内存缓冲区等都属于临界资源。 ++ 对临界资源的访问,必须互斥地进行,从逻辑上分为四个部分: + + 进入区:负责检查是否可进入临界区,若可进入则应设置**正在访问临界资源**的标志(上锁),以阻止其他进程同时进入临界区。 + + 临界区(临界段):实际访问临界资源的代码。 + + 退出区:负责解除**正在访问临界资源**的标志(解锁)。 + + 剩余区:做其他处理。 + + 进入区和退出区是实现互斥的代码段。 + +#### 互斥访问的原则 + +1. 空闲让进。临界区空闲时,可以允许一个请求进入临界区的进程立即进入临界区。 +2. 忙则等待。当已有进程进入临界区时,其他试图进入临界区的进程必须等待。 +3. 有限等待。对请求访问的进程,应保证能在有限时间内进入临界区(保证不会饥饿)。 +4. 让权等待。当进程不能进入临界区时,应立即释放处理机,防止进程忙等待。 + +### 进程互斥的软件实现 + +#### 单标志法 + +算法思想:两个进程在访问完临界区后会把使用临界区的权限转交给另一个进程。也就是说每个进程进入临界区的权限只能被另一个进程赋予。 + +```cpp +// turn表示当前允许进入临界区的进程号 +int turn = 0; + +// P0进程 +while (turn != 1); // ① +critical section; // ② +turn = 1; // ③ +remainder section; // ④ + +// P1进程 +while(turn != 0); // ⑤ +critical section; // ⑥ +turn = 0; // ⑦ +remainder section;// ⑧ +``` + +优点: + ++ turn的初值为0,即刚开始只允许0号进程进入临界区。 ++ 若P1先上处理机运行,则会一直卡在⑤,无法使用临界资源。 ++ 直到P1的时间片用完,发生调度,切换P0上处理机运行。 ++ 而代码①不会卡住P0,P0可以正常访问临界区,在P0访问临界区期间即时切换回P1,P1依然会卡在⑤。 ++ 只有P0在退出区将turn改为1后,P1才能进入临界区。 ++ 因此,该算法可以实现同一时刻最多只允许一个进程访问临界。 + +缺点: + ++ turn表示当前允许进入临界区的进程号,而只有当前允许进入临界区的进程在访问了临界区之后,才会修改turn的值。 ++ 也就是说,对于临界区的访问,一定是按P0→P1→P0→P1→……这样轮流访问。 ++ 如果P0进程一直不访问临界区,那么临界资源会被P0一直占用。 ++ 违背了空闲让进的原则。 + +#### 双标志先检查法 + +算法思想:设置一个布尔型数组flag[\],数组中各个元素用来标记各进程想进入临界区的意愿,比如`flag[0] = ture`意味着0号进程 P0现在想要进入临界区。每个进程在进入临界区之前先检查当前有没有别的进程想进入临界区,如果没有,则把自身对应的标志 flag[i]设为true,之后开始访问临界区。 + +```cpp +// 表示进入临界区意愿的数组 +bool flag[2]; +//刚开始设置为两个进程都不想进入临界区 +flag [0] = false; +flag [1] = false; + +// P0进程 +while (flag[1]); // ① +flag[0] = true; // ② +critical section; // ③ +flag [0] = false; // ④ +remainder section; + +// P1进程 +while (flag[0]); // ⑤ +flag[1] = true; // ⑥ +critical section; // ⑦ +flag[1] = false; // ⑧ +remainder section; +``` + +若按照①⑤②⑥③⑦.….的顺序执行,P0和P1将会同时访问临界区。因此,双标志先检查法的主要问题是:违反忙则等待原则。 + +### 进程互斥的硬件实现 +