本文内容,1.进程和线程 2.进程调度
特此鸣谢王道考研
本文参考王道考研的相关课程
若有侵权请联系,立删
其余笔记链接:
【王道考研】操作系统笔记 第一章_才疏学浅743的博客-CSDN博客
【王道考研】操作系统 笔记 第二章上 进程调度_才疏学浅743的博客-CSDN博客
顺序性:指处理机严格地按照程序所规定的顺序执行,即每一操作必须在下一个操作开始之前结束。 封闭性:即程序运行时独占全机资源,资源的状态(除初始状态外)只有本程序才能改变它,程序一旦开始执行,其执行结果不受外界因素影响。 可再现性:指只要程序执行时的环境和初始条件相同,当程序重复执行时,不论它是从头到尾不停顿地执行,还是“走走停停”地执行,都可获得相同的结果。
间断性:程序在并发执行时,由于它们共享系统资源,以及为完成同一项任务而相互合作,致使在这些并发执行的程序之间形成了相互制约的关系。 失去封闭性:当系统中存在着多个可以并发执行的程序时,系统中的各种资源将为它们所共享,致使其中任一程序在运行时,其他环境都必然会受到其他程序的影响。 不可再现性:程序在并发执行时,由于失去了封闭性,也将导致其又失去可再现性。
从上面的概念我们可以知道 程序在并发执行时,由于失去了封闭性,其计算结果必将与并发程序的执行速度、方向有关,从而使程序的执行失去了可再现性。 换言之,程序经过多次执行后,虽然它们执行时的环境和初始条件相同,但得到的结果却各不相同。 因为大部分程序执行要求最终结果相同,比如修改数据库。所以,通常的程序是不能参与并发执行的。为了能使程序并发执行,并对并发执行的程序加以描述和控制,引入了“进程”的概念。 引入进程的目的是为了使其进程实体能和其他进程实体并发执行,实现操作系统的并发性和共享性(最基本的两个特征)。
原来的太混乱了,只要有秩序的执行,划归规定就可以实现正确并发。 引入进程相当于是为静态的程序,增加了运行状态的信息以及数据存储位置的信息。使得我们知道程序执行状态,变成动态的执行。 传统方法,程序执行是数据和程序分别放在内存的特定位置,比如数据在内存高地址位,代码指令在内存低地址位。这导致不能进行并发执行,因为特定部位不能分别不同程序的数据。 引入进程,PCB告知程序执行状态,方便用时间片的方式暂停程序。程序段和代码段记录数据位置,每个程序分别记录,防止错乱。
程序:是静态的,就是个存放在磁盘里的可执行文件。 进程:是动态的,是程序的一次执行过程。 同一个程序多次执行会对应多个进程。 进程实体(进程映像):是静态的文件,相当于增加了PCB和数据段的程序。
由程序段、相关的数据段和PCB三部分便构成了进程实体(又称进程映像)。 注:严格来说,进程实体和进程并不一样, 进程实体是静态的,是组成进程的三部分数据的集合。 进程则是动态的。不过,除非题目专门考察二者区别,否则可以认为进程实体就是进程。因此我们也可以说“进程由程序段、数据段、PCB三部分组成”
如何判断一个数据在PCB还是在程序段、数据段?
进程描述信息:PID UID
进程控制与管理信息:进程状态,CPU状态
资源分配清单:文件位置,使用哪个I/O
处理机相关信息:实现内核态、用户态转换
另一种分类方式:
PCB的定义: 为了使参与并发执行的每个程序(含数据)都能独立地运行,在操作系统中必须为之配置一个专门的数据结构,称为进程控制块(PCB)。 PCB是进程存在的唯一标志。 PCB是给操作系统用的,程序段和数据段才是给进程自己用的。所谓创建进程,实质上是创建进程映像中的PCB,而撤销进程,实质上是撤销进程的PCB。
PCB的内容由来: 对应进程描述信息,当进程被创建时,操作系统会为该进程分配一个唯一的、不重复的“身份证号”—— PID(Process ID,进程ID)。操作系统区分各个进程就是通过PID以及进程所属用户ID(UID)来区分的。所以操作系统要记录PID、UID, 对应资源分配清单,还要记录给进程分配了哪些资源(如:分配了多少内存、正在使用哪些I/O设备、正在使用哪些文件), 对应进程控制与管理信息,还要记录进程的运行情况(如:CPU使用时间、磁盘使用情况、网络流量使用情况等)。 这些信息都被保存在PCB中。操作系统需要对各个并发运行的进程进行管理,但凡管理时所需要的信息,都会被放在PCB中。操作系统就是利用PCB来描述进程的基本情况和活动过程,进而控制和管理进程。PCB是进程存在的唯一标志。
从不同角度,进程可以有不同的定义,比较典型的定义有⭐: ①进程是程序的一次执行过程。 ②进程是一个程序及其数据在处理机上顺序执行时所发生的活动。 ③进程是具有独立功能的程序在一个数据集合上运行的过程,它是系统进行资源分配和调度的一个独立单位。
引入进程实体后,我们可以把操作系统中的进程定义为:“进程是进程实体的运行过程,是系统进行资源分配和调度的一个独立单位。” 要注意这里说的系统资源是指处理机、存储器和其他设备服务于某个进程的“时间”, 例如把处理机资源理解为处理机的时间片才是准确的。因为进程是这些资源分配和调度的独立单位,即“时间片”分配的独立单位,这就决定了进程一定是一个动态的、过程性的概念。 进程是一个具有独立功能的程序关于某个数据集合的一次运行活动。它可以申请和拥有系统资源,是一个动态的概念,是一个活动的实体。它不只是程序的代码本身,还包括当前的活动,通过程序计数器的值和处理寄存器的内容来表示。
进程是由多道程序的并发执行而引出的,和程序是两个截然不同的概念。它拥有以下特征:
动态性:进程是程序的一次执行,它有着创建、活动、暂停、终止等过程,具有一定的生命周期,是动态地产生、变化和消亡的。动态性是进程最基本的特征。
并发性:指多个进程实体同时存于内存中,能在一段时间内运行。并发性是进程的重要特征,同时也是操作系统的重要特征。引入进程的目的就是是程序能与其他进程的程序并发执行,以提高资源利用率。
独立性:指进程实体是一个能独立运行、独立获得资源和独立接受调度的基本单位。凡未建立PCB的程序,都不能作为一个独立的单位参与运行。
异步性:由于进程的相互制约,使得进程具有执行的间断性,即进程按各自独立的、不可预知的速度向前推进。异步性会导致执行结果的不可再现性,所以在操作系统中必须配置相应的=进程同步机制。
结构性:每个进程都配置一个PCB对其进行描述。
线性方式。即将系统中所有的PCB都组织在一张线性表中,将该表的首地址存放在内存的一个专用区域中。该方法实现简单、开销小,但每次查找时的需要扫描整张表,因此适合数目不多的系统。
链接方式。即把具有相同状态进程的PCB分别通过PCB中的链接字链接成一个队列。
通过运行队列判断多核
索引方式。即系统根据所有进程状态的不同,建立几张索引表。
运行态——进程得到时间片正在运行,其他资源✅ CPU✅
就绪态——进程等待时间片轮到他,其他资源✅ CPU❌
阻塞态——只能由运行态而来,只能先转换到就绪态才能回到运行态,其他资源❌ CPU❌
创建态——申请PCB
终止态——正在结束中ing,意外中断或正常结束。
阻塞态只能由 运行态主动进入,只能被动进入就绪态。
就绪态—>运行态,进程被调度
运行态—>就绪态,时间片到,或CPU被其他高优先级的进程抢占
运行态—>阻塞态,等待系统资源分配,或等待某事件发生(主动行为)
阻塞态—>就绪态,资源分配到位,等待的事件发生(被动行为)
创建态—>就绪态,系统完成创建进程相关的工作
运行态—>终止态,进程运行结束,或运行过程中遇到不可修复的错误
简单来说:进程控制就是要实现进程状态转换
创建进程——初始化PCB,分配系统资源
进程切换
创建态TO就绪态,就是直接放入CPU处理的就绪队列
就绪态TO运行态,CPU修改PCB状态即可
进程终止
运行态TO终止态,就是撤销PCB
进程的阻塞和唤醒
运行态TO阻塞态,修改PCB状态为“阻塞态”
阻塞态TO就绪态,修改PCB状态,响应阻塞时间或分配相应的资源后,放入就绪队列
可以看出,无论哪个进程控制原语,要做的无非三类事情: ①更新PCB中的信息(修改进程状态,保存/恢复运行环境) ②将PCB插入合适的队列 ③分配/回收资源
进程控制会导致进程状态的转换。无论哪个原语,要做的无非也是三类事情: 1.更新PCB中的信息(如修改进程状态标志、将运行环境保存到PCB、从PCB恢复运行环境) a.所有的进程控制原语一定都会修改进程状态标志 b.剥夺当前运行进程的CPu使用权必然需要保存其运行环境c.某进程开始运行前必然要恢复期运行环境 2.将PCB插入合适的队列 3.分配/回收资源
举例来说:可以看出来就是修改PCB的state状态值。
原语是内核中最接近硬件的部分,执行特点是一气呵成的执行完所有语句。 原子性的实现需要“关中断”“开中断”特权指令,关闭中断CPU检查使执行时无法被中断。 正常情况:CPU每执行完一条指令都会例行检查是否有中断信号需要处理,如果有,则暂停运行当前这段程序,转而执行相应的中断处理程序。 CPU执行了关中断指令之后,就不再例行检查中断信号,直到执行开中断指令之后才会恢复检查,才会去执行关中断期间的外部中断程序。这样,关中断、开中断之间的这些指令序列就是不可被中断的,这就实现了“原子性”。
注意,进程切换与处理机模式切换是不同的。 处理机模式切换时,处理机逻辑上可能还在同一进程中运行。 若进程因中断或异常进入核心态运行,执行完后又回到用户态刚被中断的程序运行,则操作系统只需恢复进程进入内核时所保存的CPU现场,而无须改变当前进程的环境信息。 但若要切换进程,当前运行进程改变了,则当前进程的环境信息也需要改变。 运行环境信息称为进程的上下文;处理机状态信息称为处理机的上下文。
阻塞态是暂时停止运行,比如等待IO操作
进程阻塞是进程自身的一种主动行为(挂起是被动的),也因此只有处于核心态的进程(拥有CPU),才可能将其转为阻塞态。 阻塞原语(Block原语)和唤醒原语(Wakeup原语)是一对作用恰好相反的原语,必须成对使用
进程通信:就是进程之间的信息交换。进程通信需要操作系统支持
进程是分配系统资源的单位(包括内存地址空间),因此各进程拥有的内存地址空间相互独立。为了保证安全,一个进程不能直接访问另一个进程的地址空间。 进程之间不能直接访问对方的资源,但是需要相互交换信息,比如,抖音分享视频链接。此时就需要进程通信
为避免出错,各个进程对共享空间的访问应该是互斥的。各个进程可使用操作系统内核提供的同步互斥工具(如P、V操做) 操作系统只负责为通信进程提供可共享使用的存储空间和同步互斥工具,而数据交换则由用户自己安排读/写指令完成。
比如共享空间里只能放一个长度为10的数组。这种共享方式仅适用于传递相对少量的数据,速度慢、限制多,是一种低级通信方式。
操作系统在内存中划出一块共享存储区,数据的形式、存放位置都由通信进程控制,而不是操作系统。这种共享方式速度很快,是一种高级通信方式。
PV操作概念:操作系统中的一种同步机制,实现对于并发进程中临界区的管理。 并发进程分为两种:
①无交互的并发进程:每个进程是相互独立的,谁也不影响谁,基本不会用到PV操作。
②有交互的并发进程:多个进程共享资源,一个进程的运行,有可能会被外界的原因而中断,且断点不固定。进程执行的相对速度不能由进程自己来控制,于是就会导致并发进程在共享资源的时出现与时间有关的错误。
临界区:并发进程中与共享变量有关的程序段都称为临界区。
P操作:申请资源操作。
V操作:释放资源操作。
信号量S:用来记录资源数量,看是否能满足申请资源的操作。
例如:S=3 表示三个可用空闲资源,S<0表示可用空闲资源无,进程申请要进入等待队列中。 P(S):S <—— S - 1 ** 如果S >= 0,进程继续执行** ** 如果S < 0,进程停止执行,放入信号量等待队列中。** V(S):S <—— S +1 ** 如果S > 0,进程继续执行;** ** 如果S <= 0,唤醒等待队列中的一个进程。**
例子:银行排队取号,按号叫人,值得一提的是窗口上有个大大的LED屏,显示着有几个人在等待,一共三个窗口,这时,10个人想办理业务。(资源-窗口,人-进程,大屏幕-S,很符合了吧) 没人在窗口办理业务,屏幕:3个窗口可以办理; 1人在窗口办理业务,屏幕:2个窗口可以办理; 2人在窗口办理业务,屏幕:1个窗口可以办理; 3人在窗口办理业务,屏幕:0个窗口可以办理; 又来一个人取号,屏幕:1人在等待; 。。。。。 第十个人来了,屏幕:7人在等待; 以上取号都是申请资源操作 P(S),取号就相当于对屏幕上信号量减一,即 P(S) 中的 S-1 , 减成负数时就要在等待区等待。 当一个人办理完业务,将释放一个窗口,则屏幕信号量 V(S) 中的 S 加1, 1人办理完业务,屏幕:6人在等待(一人去了窗口办理业务)
管道通信就是用一个传输字符流格式的管道(共享文件)进行通信,
数据以字符流的形式写入管道,当管道写满时,写进程的write()系统调用将被阻塞,等待读进程将数据取走。
当读进程将数据全部取走后,管道变空,此时读进程的read()系统调用将被阻塞。
如果没写满,就不允许读。 如果没读空,就不允许写。 管道中的数据一旦被读出,就彻底消失。
因此,当多个进程读同一个管道时,可能会错乱。对此,通常有两种解决方案:①一个管道允许多个写进程,一个读进程(2014年408真题高教社官方答案);②允许有多个写进程,多个读进程,但系统会让各个读进程轮流从管道中读数据(Linux 的方案)。
管道缓冲区大小和操作系统内存页面一样,Linux就是4KB。
管道的底层数据结构是一个循环队列。
管道只能采用半双工通信,
进程间的数据交换以格式化的消息(Message)为单位(不同环境下,消息格式不同)。 进程通过操作系统提供的“发送消息/接收消息”两个原语进行数据交换。 应用场景: 若通信的进程之间不存在可直接访问的共享空间,则必须利用操作系统提供的消息传递方式实现进程通信。 在计算机网络中,消息又称为报文;在微内核与服务器之间的通信也都是采用了消息传递机制。
基于消息传递的通信方式属于高级通信方式,因其实现方式的不同,可进一步分为2类:
直接通信
间接通信
发送进程直接把消息发送给接收进程,并将它挂在接收进程的消息缓冲队列上,接收进程从消息缓冲队列中取得消息。
注:由于PCB是保存在操作系统内核中,所以消息队列也是在内核中。
发送进程把消息发送到某个中间实体,接收进程从中间实体取得消息。 这种中间实体一般称为信箱,这种通信方式又称信箱通信方式。该通信方式广泛应用于计算机网络中,相应的通信系统称为电子邮件系统。
线程就是一个进程的若干功能,比如QQ可以同时使用文字聊天和视频聊天两种功能。 传统的进程只能顺序的实现若干功能,但是引入线程技术,可以让线程并发的执行,也就可以同时实现若干功能了。
可以把线程理解为“轻量级进程”。LWP(Light Weight Process) 线程,是一个基本的CPU执行单元,也是程序执行流的最小单位。 引入线程后,进程只作为除CPU之外的系统资源的分配单元(如打印机、内存地址空间等都是分配给进程的)。线程则作为处理机的分配单元。
由线程ID、程序计数器、寄存器集合和堆栈组成。
线程是进程中的一个实体,是被系统独立调度和分派的基本单位
线程自己不拥有系统资源,只拥有一点在运行中必不可少的资源,但它可与同属一个进程的其他线程共享进程所拥有的全部资源。
一个线程可以创建和撤销另一个线程,同个进程中的多个线程之间可以并发执行。由于线程之间的相互制约,致使线程在运行中呈现出间断性
调度:在传统的OS中,进程是资源分配、调度的基本单位。引入线程后,进程是资源分配的基本单位,线程是调度的基本单位 在同一进程中,线程的切换不会引起进程切换。 在不同进程中进行线程切换,如从一个进程内的线程切换到另一个进程中的线程时,会引起进程切换。
拥有资源:不论是传统操作系统、还是有线程的操作系统,进程都是拥有资源的基本单位,而线程不拥有系统资源(只有一点必不可少的资源),但线程可以访问其隶属进程的系统资源。
并发性:在传统的OS中,只有进程间并发。在引入线程后,各线程间也能并发,提升了并发度。 系统开销:传统的进程间并发时,需要切换进程的运行环境,系统开销很大。而线程间并发时,如果是同一进程内的线程切换,则不需要切换进程环境,系统开销小。
线程的实现可以分为两类:用户级线程(User-Level Thread,ULT) 和内核级线程(Kernel-Level Thread,KLT)。内核级线程又称内核支持的线程。(按切换时是否依赖内核进行区分)
历史背景:早期的操作系统(如:早期Unix)只支持进程,不支持线程。当时的“线程”是由线程库实现的。 在用户级线程中,有关线程管理(线程的创建、撤销和切换等)的所有工作都由应用程序完成,内核意识不到线程的存在。应用程序可以通过使用线程库设计成多线程程序。在用户级线程的系统中,其调度仍是以进程为单位。
很多编程语言提供了强大的线程库,可以实现线程的创建、销毁、调度等功能。
用户级线程特点: 1)用户级线程由应用程序通过线程库实现,所有的线程管理工作都由应用程序负责(包括线程切换)。 2)用户级线程中,线程切换可以在用户态下即可完成,无需操作系统干预。 3.)在用户看来,是有多个线程。但是在操作系统内核看来,并意识不到线程的存在。“用户级线程”就是“从用户视角看能看到的线程”。
优缺点: 优点:用户级线程的切换在用户空间即可完成,不需要切换到核心态,线程管理的系统开销小,效率高。用户级线程的实现与OS无关,因为对于线程管理的代码是属于用户程序的一部分,所有的应用程序都可以对之进行共享。因此,用户级线程甚至可以在不支持线程机制的操作系统平台上实现。 缺点:当一个用户级线程被阻塞后,整个进程都会被阻塞,并发度不高。多个线程不可在多核处理机上并行运行,因为内核每次分配给一个进程的仅有一个CPU,因此,进程中仅有一个线程能执行,在该线程放弃CPU1之前,其他线程只能等待。
在内核级线程中,线程管理的所有工作由内核完成,应用程序没有进行线程管理的代码,只有一个到内核级线程的编程接口。内核为基础及其内部的每个线程维护上下文信息,调度也在内核基于线程架构的基础上完成,调度是以线程为单位。
内核级线程特点: 1)内核级线程的管理工作由操作系统内核完成。 2)线程调度、切换等工作都由内核负责,因此内核级线程的切换必然需要在核心态下才能完成。 3)操作系统会为每个内核级线程建立相应的TCB(Thread Control Block,线程控制块),通过TCB对线程进行管理。“内核级线程”就是“从操作系统内核视角看能看到的线程”。
优缺点: 优点:当一个线程被阻塞后,别的线程还可以继续执行,并发能力强。多线程可在多核处理机上并行执行。 缺点:一个用户进程会占用多个内核级线程,线程切换由操作系统内核完成,需要切换到核心态(用户进程的线程在用户态运行,而线程调度和管理在内核实现的),因此线程管理的成本高,开销大。
不论是进程还是线程,都必须直接或间接地取得内核的支持。由于内核支持线程可以直接利用系统调用为它服务,故线程的控制相当简单; 而用户级线程必须借助于某种形式的中间系统的帮助才能取得内核的服务,故在对线程的控制上要稍微复杂些。
在支持内核级线程的系统中,根据用户级线程和内核级线程的映射关系,可以划分为几种多线程模型。
就是纯粹的内核级线程
一个用户级线程映射到一个内核级线程。每个用户进程有与用户级线程同数量的内核级线程。 优点:当一个线程被阻塞后,别的线程还可以继续执行,并发能力强。多线程可在多核处理机上并行执行。 缺点:一个用户进程会占用多个内核级线程,线程切换由操作系统内核完成,需要切换到核心态,因此线程管理的成本高,开销大。
多个用户级线程,运行在一个内核的线程上
即多个用户级线程映射到一个内核级线程。这些用户线程一般属于一个进程,运行在该进程的用户空间,对这些线程的调度和管理也是在该进程的用户空间中完成。仅当用户线程需要访问内核时,才将其映射到一个内核控制线程上,但每次只允许一个线程进行映射
优点:用户级线程的切换在用户空间即可完成,不需要切换到核心态,线程管理的系统开销小,效率高。 缺点:当一个用户级线程被阻塞后,整个进程都会被阻塞,并发度不高。多个线程不可在多核处理机上并行运行。
重点重点重点: 操作系统只“看得见”内核级线程,因此只有内核级线程才是处理机分配的单位。
n 用户及线程映射到 m 个内核级线程(n >= m)。每个用户进程对应 m 个内核级线程。 克服了多对一模型并发度不高的缺点(一个阻塞全体阻塞),又克服了一对一模型中一个用户进程占用太多内核级线程,开销太大的缺点。
可以这么理解:
用户级线程是“代码逻辑”的载体。
内核级线程是“运行机会”的载体。
内核级线程才是处理机分配的单位。
例如:多核CPU环境下,上面这个进程最多能被分配两个核。一段“代码逻辑”只有获得了“运行机会”才能被CPU执行。内核级线程中可以运行任意一个有映射关系的用户级线程代码,只有两个内核级线程中正在运行的代码逻辑都阻塞时,这个进程才会阻塞。
【高级】什么时候从虚拟存储器的外存的后备队列把“作业”放入内存?
【中级】什么时候把内存中,阻塞的进程,也就是此时不能运行的进程放入外存?进入挂起状态,PCB不调出内存。
它的调度对象是作业。其主要功能是根据某种算法,决定将外存上处于后备队列中的哪几个作业调入内存,为它们创建进程、分配必要的资源,将它们放入到就绪队列。 高级调度主要用于多道批处理系统中,而其他系统通常不配置作业调度,作业调度的执行效率较低,通常为几分钟一次。 特点:
调度对象是:作业
调度范围是:是外存和内存之间的调度。是把外存中的“作业”调入到内存中执行
“作业”只能调入一次,调出一次。可以运行作业的时候调入,当作业运行结束才调出。
其实也就是进程有中断回到就绪队列的过程,但是作业一旦开始运行就要执行完毕。并且,一个作业可以分为多个进程,这多个进程可以在内存和外存中进进出出
高级调度不考虑作业调出。因为调出的条件就是运行结束了,所以OS只需要管作业什么时候调入。
在某些操作系统中,作业(job)是计算机操作者(或是一个叫做作业调度器的程序)交给操作系统的执行单位。 作业包括程序、相应的数据和作业说明书
具体例子: 进程是CPU的执行单位 一个作业通常分为多个进程。 运行QQ算是一个进程,但是交付给OS的需要的是多个进程组成的“作业”
其作用是提高内存利用率和系统吞吐量。为此,应将那些暂时不能运行的进程调至外存等待,把此时的进程状态称为挂起态。当它们已具备运行条件且内存又稍有空闲时,由中级调度来决定把外存上那些已具备运行条件的就绪进程,再重新调入内存,并修改其状态为就绪态,挂在就绪队列上等待。 特点:
作用单位是进程。
调度范围是,内存、外存。
进程调出外存时进入挂起状态,PCB仍在内存中受到到监控。
有两种挂起状态
多了七条边,七个转化情况
就绪态与就绪挂起态:如果没有内存了,处于就绪态的进程就会调入外存变成就绪挂起。
也就是说,就绪挂起与就绪的区别,就是其实都是就绪态,只不过是内存中的就绪态还是外存中的就绪态
阻塞挂起vs就绪挂起:阻塞挂起 先回到内存成为阻塞态还是直接先变成** 就绪挂起和**OS的类型有关系。
它的调度对象是进程或内核级线程。按照某种策略从就绪队列中选取一个进程,将处理机分配给它。进程调度是操作系统中最基本的一种调度,在一般的操作系统中都必须配置进程调度。进程调度的频率很高,一般几十毫秒一次。 特点:
调度对象是:进程或内核级线程
调度范围是:就绪队列(就绪态)到运行队列(运行态)
进程调度(低级调度),是从就绪队列中选择一个进程到运行队列
进程主动放弃处理机
①进程正常终止
②运行过程中发生异常而终止
③进程主动请求阻塞(如 等待I/O)
当进程被动放弃处理机
①分给进程的时间片用完
②有更紧急的事需要处理(如 I/O中断)
③有更高优先级的进程进入就绪队列
①在处理中断的过程中。中断处理过程复杂,与硬件密切相关,很难做到在中断处理过程中进行进程切换。 ②在访问内核程序临界区期间时不能进行调度与切换;而在访问普通临界区时可以进行调度与切换。(注意:进程调度和切换程序都是操作系统内核程序) ③在原子操作过程中(原语)。原子操作不可中断,要一气呵成(如之前讲过的修改PCB中进程状态标志,并把PCB放到相应队列就属于原子操作)
临界资源:一个时间段内只允许一个进程使用的资源。各进程需要互斥地访问临界资源。 临界区:访问临界资源的那段代码。 内核程序临界区:一般是用来访问操作系统内核中的数据结构或数据的,比如进程的就绪队列(由各就绪进程的PCB组成) 普通临界资源:就是像普通I/O设备什么的,比如,打印机,进程访问这些资源的时候,很慢,会自动阻塞,等待资源使用完成。
有如下的判断题:
进程切换的目的:就是为了防止某个进程长时间等待阻塞时,其他进程不能干活。 操作方式是:先把你访问的资源作为临界区上锁,别人就无法访问了。等到时间片轮到你,你就可以恢复工作区继续工作了。 推理 为什么内核程序临界区不行,普通的可以?
内核程序的邻接区很重要,很多程序都等着用,长时间上锁影响OS管理系统。比如:就绪队列。设想假如进行进程切换了,则就绪队列就被封锁起来了。此时运行区的进程也许可以访问IO,不能让就绪态的进程补充进入运行队列了。这就影响了OS的使用。
普通临界区,比如:打印机外设。我输入要打印的pdf,然后等待打印完毕弹出(“打印完毕”)。OS为了防止CPU长时间等待,进行了切换。打印机被上锁,没人可以输入新的pdf让打印机打印,一段时间之后,打印机打印完毕,又恰逢时间片轮到此进程,就可以弹出(“打印完毕”)了。
进程切换越频繁,并发度越高❌
狭义的进程调度 指的是从就绪队列中选择一个要运行的进程。(这个进程可以是刚刚被暂停执行的进程,也可能是另一个进程,后一种情况就需要进程切换) 进程切换 进程切换是指一个进程让出处理机,由另一个进程占用处理机的过程。 广义的进程调度 包含了选择一个进程和进程切换两个步骤。 进程切换的内容: ①对原来运行进程各种数据的保存 ②对新的进程各种数据的恢复(如:程序计数器、程序状态字、各种数据寄存器等处理机现场信息,这些信息一般保存在进程控制块)
只允许进程主动放弃处理机。即使在运行过程中即便有更紧迫的任务到达,当前进程依然会继续使用处理机。
特点: 这种方法实现简单,系统开销小但是无法及时处理紧急任务 适合于早期的批处理系统,不能用于分时系统和大多数的实时系统。
当一个进程正在处理机上执行时,如果有一个更重要或更紧迫的进程需要使用处理机,则立即暂停正在执行的进程,将处理机分配给更重要紧迫的那个进程。
特点: 这种方法可以优先处理更紧急的进程,也可实现让各进程按时间片轮流执行的功能(通过时钟中断)。 适合于分时操作系统、实时操作系统。采用剥夺式的调度,对提高系统吞吐率和响应效率都有明显的好处。
比起背公式,更多要用刷题学会计算
单位 作业(个)/时间
周转时间定义,是指从作业被提交给系统开始,到作业完成为止的这段时间间隔。 包括四个部分:
作业在外存后备队列上等待作业调度〈高级调度)的时间、
进程在就绪队列上等待进程调度(低级调度)的时间、
进程在CPU上执行的时间、
进程等待I/o操作完成的时间。阻塞等待
理解:
周转时间vs等待时间:周转时间 = 等待时间 + 执行时间
进程等待时间 ≠ 作业等待时间
进程等待时间不包括IO阻塞时间
First Come First Serve
Shortest Job First
Shortest Remaining Time Next
如果时间片太大,使得每个进程都可以在一个时间片内就完成,则时间片轮转调度算法退化为先来先服务调度算法,并且会增大进程响应时间。因此时间片不能太大。
另一方面,进程调度、切换是有时间代价的(保存、恢复运行环境),因此如果时间片太小,会导致进程切换过于频繁,系统会花大量的时间来处理进程切换,从而导致实际用于进程执行的时间比例减少。可见时间片也不能太小。
开销不超过1%
动态的优先级算法
这个很复杂,综合了好几种算法
注意它的优点,非常强。
算法描述,简单来说就是
所有的进程,比如进程A首先进入一级队列,然后执行1时间片;
接着,A进入二级队列。此时,如果一级队列没有进程,就执行二级队列里面的进程A。
进程A在二级队列里面执行之后,A进入三级队列,而在三级队列执行之后还是回到三级队列。