操作系统-进程
2020-06-01 17:10:44 3 举报
AI智能生成
操作系统-进程
作者其他创作
大纲/内容
进程控制
基本概念
什么是进程控制?
进程控制的主要功能时对系统中的所有进程实时有效的管理,它具有创建新进程、撤销已有进程、实现进程状态转换等功能。
简化来说,进程控制就是要实现进程状态转换
如何实现进程控制?
用“原语”实现
为什么要用原语来实现进程控制?
如果不用原语,就有可能导致操作系统中的某些关键数据结构信息不统一的情况,这会映像操作系统进行别的管理工作
如何实现原语的原子性?
可以用“关中断指令”和“开中断指令”,这两个特权指令来实现原子性。
正常情况下:CPU没执行完一条指令都会例行检查是否有中断信号需要处理,如果有,则暂停运行当前这段程序,转而执行响应的中断处理程序。
CPU执行了关中断指令后,就不再例行检查中断信号,直到执行开中断指令之后才会恢复检查。
这样,关中断、开终端之间的这些指令序列就是不可被中断的,这就实现了“原子性”
如果开、关指令中有了外部中断信号,则会等待执行开指令完毕后执行中断
开、关指令是特权指令,如果用户能够使用则可以一直霸占CPU,所以不能让用户使用
进程控制相关的原语
进程的创建
创建原语
申请空白PCB
为新进程分配所需资源
初始化PCB
将PCB插入就绪队列
引起进程创建的事件
用户登录
分时系统中,用户登录成功,系统会简历为其建立一个新的进程
作业调度
多道批处理系统中,有新的作业放入内存是,会为其建立一个新的进程
提供服务
用户向操作系统提出某些请求时,会新建一个进程处理该请求
应用请求
由进程主动请求创建一个子进程
进程的终止
撤销原语
从PCB集合中找到终止进程的PCB
若进程正在执行,立即剥夺CPU,将CPU分配给其他进程
终止其所有子进程
将该进程拥有的所有资源归还给父进程或操作系统
删除PCB
引起进程的事件
正常结束
异常结束
外界干预
进程的阻塞
阻塞原语
找到阻塞的进程对应的PCB
保护进程运行现场,将PCB的状态信息设置为“阻塞态”,暂时停止进程运行
将PCB插入相应事件的等待队列
引起进程阻塞的事件
需要等待系统分配某种资源
需要等待相互合作的其他进程完成工作
进程的唤醒
唤醒原语
在事件等待队列中找到PCB
将PCB从等待队列中溢出,设置进程为就绪态
将PCB插入就绪队列,等待被调度
引起进程唤醒的事件
等待的事件发生
进程的切换
切换原语
将运行环境信息存入PCB
PCB移入相应队列
选择另一个进程执行,并更新其PCB
根据PCb恢复新进程所需的运行环境
引起进程切换的事件
当前进程时间片到
有更高优先级的进程到达
当前进程主动阻塞
当前进程终止
进程通信
什么是进程通信?
指程序之间的消息交换
进程是分配系统资源的单位(包括内存地址空间),因此各进程拥有的内存地址空间相互独立
为了保证安全,一个进程不能直接访问另一个进程的地址空间
但是进程之间的信息交换优势必须实现的,为了保证进程间的安全通信,操作系统提供了如下方法
共享存储
进程之间不允许互相访问,操作系统为其提供了共享空间
两个进程对共享空间的访问必须是互斥的(互斥访问通过操作系统提供的工具实现)
操作系统只负责提供共享空间各同步互斥工具(如P、V操作)
基于数据结构的共享
比如共享空间里只能放一个长度为10的数组。这种共享方式速度慢、限制多,是一种低级通信方式
基于存储区的共享
基于存储区的共享:在内存中画出一块共享存储区,数据的形式、存放位置都由进程控制,而不是操作系统,相比之下,这种共享方式速度更快,是一种高级通信方式
消息传递
进程间的数据交互以格式化的消息(message)为单位。进程通过操作系统提供的“发送消息/接收消息”两个原语进行数据交换
消息(message)
消息头
发送进程ID、接受进程ID、消息类型、消息长度等格式化的信息(计算机网络中发送的“报文”其实就是一种格式化的消息)
消息体
直接通信方式
消息直接挂到接收进程的消息缓冲队列上
间接通信方式
消息要发送到中间实体(信箱)中
管道通信
“管道”是指用于连接读写进程的一个共享文件,又名pipe文件。其实就是在内存中开辟一个大小固定的缓冲区
1.管道只能采用半双工通信,某一时间段内只能实现单向的传输。如果要实现双向同时通信,则需要设置两个管道
2.各个进程要互斥地访问管道
3.数据以字符流的形式写入管道,当管道写满时,写进程的write()系统掉哦那个将被阻塞,等待读进程将数据读走,当度进程将数据全部被读走,管道为空,此时读进程的read()系统调用将被阻塞。
4.如果没有写满,就不允许读,如果没读空,就不允许写
5.管道中的数据一旦被读出,就从管道中被抛弃,这就意味着读进程最多只能有一个,否则可能会有读错数据的情况。
处理机调度
基本概念
当有一堆任务要处理,但由于资源有限,这些事情没法同时处理。这就需要确定某种规则来决定处理这些人物的顺序,这就是“调度”研究的问题
在多道程序系统中,进程的数量往往是多余处理机的个数的,这样不可能同时并行地处理各个进程
处理机调度,就是从就绪队列中按照一定的算法选择一个进程并将处理机分配给它运行,以实现进程的并发执行
三个层次
高级调度(作业调度)
由于内存空间优先,有时无法将用户提交的作业全部放入内存,因此就需要确定某种规则来决定将作业调入内存的顺序
高级调度(作业调度)。按一定的原则从外存上处于后备队列的作业中挑选一个(或多个)作业,给他们分配内存等必要资源,并建立相应的进程(建立PCB),以使它(们)获得竞争处理机的权利。
高级调度使辅存(外存)与内存之间的调度。每个作业只调入一次,调出一次。作业调度时会建立相应的PCB,足额也调出时撤销PCB。高级调度只要时指调入问题,因为只有调入的时机需要操作系统来确定,但调出的时机必然是作业运行结束才调出
中级调度(内存调度)
引入了虚拟存储技术之后,可将暂时不能运行的进程调至外存等待。等它具备了运行条件且内存又稍有空闲时,再重新调入内存
目的是为了提高内存利用率和系统吞吐量
暂时调到外存等待的进程状态为挂起状态。值得注意的是,PCB并不会一起调到外存,而是会常驻内存。PCB中会记录进程数据在外存中的存放位置,进程状态等信息,操作系统通过内存中的PCB来保持对各个进程的监控、管理。被挂起的进程PCB会被放到挂起队列中。
中级调度(内存调度),就是要决定将哪个处于挂起状态的进程重新调入内存
一个进程可能被多次调出、调入,因此中级调度发生的频率要比高级调度更高
低级调度(进程调度)
主要的任务是按照某种方法和策略从就绪队列中选取一个进程,将处理机分配给它
进程调度是操作系统中最基本的一种调度,在一般的操作系统中都必须配置进程调度
进程调度的频率很高,一般几十毫秒一次
三层调度的联系、对比
补充知识
进程的“挂起态”
暂时调到外存等待的进程状态为挂起状态(挂起态)
挂起态又可进一步细分为就绪挂起、阻塞挂起两种状态
七状态模型
挂起和阻塞的区别
两种状态都是暂时不能获得CPU的服务,但是挂起态是将进程映像调到外存中去了,而阻塞态下进程映像还在内存中
有的操作系统会把就绪挂起、阻塞挂起分为两个挂起队列,设置会根据阻塞原因再把则色挂起进程细分为多个队列
三层调度的联系、对比
进程调度
时机
什么时候需要进程调度
主动放弃
进程正常终止
运行过程中发生异常而终止
主动阻塞(如等待I/O)
被动放弃
分给进程的时间片用完
有更紧急的事情需要处理
有更高优先级的进程进入就绪队列
什么时候不能进行进程调度?
在处理中断的过程中
进程在操作系统内核程序临界区中
原子操作过程中(原语)
一些补充
进程在操作系统内核程序临界区中不能进行调度与切换
进程处于临界区时不能进行处理机调度(错误)
临界资源:一个时间段内只允许一个进程使用的资源。各进程需要互斥地访问临界资源
临界区:访问临界资源的那段代码
内核程序临界区一般是用来访问某种内核数据结构的,比如进程的就绪队列(由各就绪进程的PCB组成)
切换与过程
狭义的“调度”和“切换”的区别
狭义的进程调度指的是从就绪队列中选中一个要运行的进程。(这个进程可以是刚刚被暂停执行的进程,也可能是另一个进程,后一种情况就需要进程切换)
进程切换是指一个进程让出处理机,由另一个进程占用处理机的过程
广义的进程调度包含了选择一个进程和进程切换两个步骤
切换过程
对原来运行进程各种数据的保存
对新的进程各种数据的恢复
重要结论:进程调度、切换是有代价的,并不是调度越频繁,并发度就越高
方式
非剥夺调度方式(非抢占式)
只能由当前运行的进程主动放弃CPU
剥夺调度方式(抢占式)
可由操作系统剥夺当前进程的CPU使用权
调度算法的评价指标
CPU利用率
指CPU“忙碌”的时间占总时间的比例
利用率 = 忙碌的时间 / 总时间
有时候也会计算某种设备的利用率,与CPU同理
EG:某计算机只支持单道程序,某个作业先在CPU上运行5秒,之后在打印机上输出5秒,之后再执行5秒
则CPU利用率(5+5)/(5+5+5)
打印机利用率5/15
系统吞吐量
单位时间内完成作业的数量
系统吞吐量 = 总共完成了多少道作业 / 总共花了多少时间
EG:某计算机处理完10道作业,共花费100秒,则系统的吞吐量为?
10/100 = 0.1 道/秒
周转时间
对于计算机的用户来说,他很关心自己的作业从提交到完成花了多少时间。周转时间,是指从作业被提交给系统开始,到作业完成为止的这段时间间隔。
周转时间包括四个部分:作业在外存后备队列上等待作业调度(高级调度)的时间、进程再就绪队列上等待进程调度(低级调度)的时间、进程在CPU上执行的时间、进程等待I/O操作完成的时间。后三项在一个作业的整个处理过程中,可能发生多次。
周转时间、平均周转时间
(作业)周转时间=作业完成时间-作业提交时间
平均周转时间 = 各作业周转时间之和/作业数
有的作业运行时间段,有的作业运行时间长,因此在周转时间相同的情况下,安排不同的作业执行顺序,给用户的感觉肯定是不一样的
带权周转时间、平均带权周转时间
带权周转时间 = 作业周转时间/作业实际运行的时间 = (作业完成时间-作业提交时间) / 作业实际运行时间
平均周转时间 = 个作业带权周转时间之和 / 作业数
等待时间
计算机的用户希望自己的作业尽可能少的等待处理机
等待时间,指进程/作业处于等待处理机状态时间之和,等待时间越长,用户满意度越低
对于进程来说,等待时间就是指进程建立之后等待被服务的时间之和,在等待I/O完成的期间其实进程也是在被服务的,所以不计入等待时间
对于作业来说,不仅要考虑建立进程后的等待时间,还要加上作业在外存后备队列中等待的时间
一个作业总共需要被CPU服务多久,被I/O服务多久一般是确定不变的,因此调度算法只会影响作业/进程的等待时间。当然,与前面类似,也有“平均等待时间”来评价整体性能
响应时间
对于计算机用户来说,会希望自己提交的请求(比如通过键盘输入了一个调试命令)今早地开始被系统服务、回应。
响应时间,指从用户提交请求到首次产生响应所用的时间
进程同步、互斥问题
什么是进程同步
回顾异步:异步是指,各并发执行的进程以各自独立的、不可预知的速度向前推进
比如之前的管道通信问题,读进程与写进程并发地运行,由于并发必然导致异步行,因此“写数据”和“读数据”两个操作执行的先后顺序是不确定的。而实际应用中,又必须按照“写数据->读数据”的顺序来执行的。
解决这种异步问题,就是“进程同步”所讨论的内容
进程同步就是讨论怎么解决进程异步的问题
同步又称直接制约关系,就是指未完成某种任务而建立的两个或多个进程,这些进程因为需要某些位置上协调它们的工作次序而产生的制约关系。进程间的直接制约关系就是源于它们之间的相互合作。其实就是保证进程间的工作次序,比如写数据在前,读数据在后。
什么是进程互斥
进程的“并发”需要“共享”的支持。各个并发执行的进程不可避免的需要共享一些系统资源(比如内存,又比如打印机、摄像头这样的I/O设备)
两种资源共享方式
互斥共享方式
系统中的默写资源,虽然可以提供给多个进程使用,但一个时间段内只允许一个进程访问该资源
同时共享方式
系统中的某些资源,允许一个时间段内由多个进程“同时(宏观上)”对它们进行访问
临界资源
一个时间段内之u内需一个进程使用的资源称为临界资源。许多物理设备(比如摄像头、打印机)都属于临界资源。此外还有许多变量、数据、内存缓冲区等都属于临界资源。
对于临界资源的访问,必须互斥地进行。互斥,亦称间接制约关系。进程互斥指当一个进程访问某临界资源时,另一个想要访问该临界资源的进程必须等待。当前访问临界资源的进程访问结束,释放该资源之后,另一个进程才能去访问临界资源。
对临界资源的访问,需要互斥的进行。即同一时间段内只能允许一个进程访问该资源
对临界资源的互斥访问,可以在逻辑上分为如下四个部分:见备注,这备注挺重要的
为了实现对临界资源的互斥访问,同时保证系统整体性能,需要遵循以下原则
1.空闲让进。临界区空闲时,可以允许一个请求进入临界区的进程立即进入临界区;
2.忙则等待。当已有进程进入临界区时,其他试图进入临界区的进程必须等待;
3.有限等待。对请求访问的进程,应保证能在有限时间内进入临界区(保证不会饥饿);
4.让权等待。当进程不能进入临界区时,应立即释放处理机,防止进程忙等待。
1.空闲让进。临界区空闲时,可以允许一个请求进入临界区的进程立即进入临界区;
2.忙则等待。当已有进程进入临界区时,其他试图进入临界区的进程必须等待;
3.有限等待。对请求访问的进程,应保证能在有限时间内进入临界区(保证不会饥饿);
4.让权等待。当进程不能进入临界区时,应立即释放处理机,防止进程忙等待。
进程互斥的软件实现方法
如果系统中没有注意到进程互斥会发生什么
两个进程,A与B,如果A在使用打印机的过程中时间片用完了,接下来B上,结果就是A、B的内容混在一起了
单标志法
思想
两个进程在访问完临界区后会把使用临界区的权限交给另一个进程。也就是说,每个进程进入临界区的权限只能被另一个进程赋予
在进入区只做“检查”,不“上锁”
在退出区把临界区的使用权交给另一个进程
(相当于在退出区既给另一进程“解锁”,又给自己“上锁”)
(相当于在退出区既给另一进程“解锁”,又给自己“上锁”)
主要问题:不遵循“空闲让进”原则
双标志先检查
思想
设置一个布尔数组flag[],数组中各个元素用来标记个进程想进入临界区的一员,比如“flag[0]=true”意味着0号进程P0现在想要进入临界区,每个进程在进入临界区之前先检查当前有没有别的进程想进入临界区,如果没有,则把自身对应的标志flag[i]设为true,之后开始访问临界区
在进入区先“检查”后“上锁”,退出区“解锁”
主要问题:不遵循“忙则等待”原因在于,进入区的“检查”和“上锁”两个处理不是一气呵成的。“检查”后,“上锁”前可能会发生进程切换
双标志后检查
思想
双标志先检查的改版。先检查是后“上锁”,这个是先“上锁”,其余一样
在进入区先“加锁”后“检查”,退出区“解锁”
主要问题:不遵循“空闲让进、有限等待原则”,可能会导致“饥饿”
Peterson算法
思想
结合双标志法、但标志法的思想。如果双方都争着想进入临界区,那可以尝试“谦让”
其实就是谁最后一次做出了谦让,谁就失去了有限权
在进入区“主动争取-主动谦让-检查对方是否想进、己方是否谦让”
主要问题:不遵循“让权等待”原则,会发生“忙等”
进程互斥的硬件实现方法
中断屏蔽方法
使用“开/关中断”指令实现(与原语差不多)
优点:高效简单
缺点:只适用于但处理机;只适用于操作系统的内核进程
TestAndSet指令
(别名:TS、TestAndSetLock、TSL指令)
(别名:TS、TestAndSetLock、TSL指令)
TSL指令是用硬件实现的,执行的过程中不允许被中断,只能一气呵成。
Swap指令
信号量机制
整形信号量
用一个整数型变量作为信号量,数值表示某种资源数
整形信号量与普通整型变量的区别:对信号量只能执行初始化、P、V三种操作
存在的问题:不满足让权等待原则
记录型信号量(很重要)
S.value表示某种资源数,S.L指向等待该资源的队列
P操作中,一定是先S.value--,之后可能执行block原语
V操作中,一定是先S.value++,之后可能需要执行wakeup原语
注意:要能够自己推断在什么条件下需要执行block或wakeup
可以用记录型信号量实现系统资源的“申请”与“释放”
可以用记录型信号量实现进程互斥、进程同步
实现进程互斥
分析问题,确定临界区
设置互斥信号量,初值为1
临界区之前对信号量执行P操作
临界区之后对信号量执行V操作
实现进程同步
分析问题,找出哪里需要实现“一前一后”的同步关系
设置同步信号量,初始值为0
在“前操作”之后执行V操作
在“后操作”之前执行P操作
实现进程的前驱关系
分析问题,画出前趋图,把每一对前趋关系都看成一个同步问题
为每一对前趋关系设置同步信号量,初值为0
在每个“前操作”之后执行V操作
在每个“后操作”之前执行P操作
经典问题
生产者、消费者
问题描述
系统中有一组生产者进程和一组消费者进程,生产者进程每次生产一个产品放入缓冲区,消费者进程每次从缓冲区中去除一个产品并使用。(注:这里的“产品”理解为某种数据)
生产者、消费者共享一个初始为空、大小为n的缓冲区
只有缓冲区没满时,生产者才能把产品放入缓冲区,否则必须等待(缓冲区没满->生产者生产)
只有缓冲区不空时,消费者才能从中取出产品,否则必须等待(缓冲区没空->消费者消费)
缓冲区是临界资源,各进程必须互斥地访问(互斥关系)
PV操作题目分析步骤
1.关系分析,找出题目中描述的各个进程,分析它们之间的同步、互斥关系
2.整理思路,根据各进程的操作流程确定P、V操作的大致顺序
3.设置信号量,并根据题目条件确定信号量初值。(互斥信号量初值一般为1,同步信号量的初始值要看对应资源的初始值)
多生产者、多消费者问题
问题描述
桌子上有一只盘子,每次只能向其中放入一个水果。爸爸专门向盘子中放苹果,妈妈专门向盘子中放橘子,儿子专吃橘子,女儿专 吃苹果。仅当盘子中有自己需要的水果时,儿子或者女儿可以从盘子中取出水果。用PV操作实现上述过程。
吸烟者问题
假设一个系统中有三个吸烟者进程和一个供应者进程。每个吸烟者不停地卷烟并抽掉它,但是要卷起并抽掉一支烟,抽烟者需要三种材料:烟草、纸和胶水。三个吸烟者中,第一个拥有烟草、第二个拥有纸、第三个拥有胶水。供应者进程无限地提供三种材料,供应者每次将两种材料放桌子上,拥有剩下那种材料的吸烟者卷一根烟并抽掉它,并给供应者一个信号告诉完成了,供应者就会把另外两种材料放在桌上,这个过程一直重复(让三个吸烟者轮流地吸烟)。
读者、写者问题
有读者、写者两组并发进程,共享一个文件,当两个或两个一闪给的读进程同时访问共享数据时不会产生副作用,但若某个写进程和其他进程(读进程或写进程)同时访问共享数据是则可能导致数据不一致的错误。因此要求:(1)允许多个读者可以同时对文件进行读操作;(2)只允许一个写者往文件中写信息;(3)任一写者在完成写操作之前不允许其他读者或者写者工作;(4)写者进行写操作前,应让已有的读者和写者全部退出。
哲学家进餐
一张圆桌上坐着五位哲学家,每两个哲学家之间的桌子上摆一根筷子,桌子的中间是一碗米饭。哲学家们只进行思考和进餐,在思考时,并不影响其他人。只有哲学家饥饿时,才试图拿起左、右两根筷子(一根一根地拿起)。如果筷子已在他人手上,则需等待。饥饿的哲学家只有同时拿起两根筷子才可以开始进餐,当进餐完毕后,放下筷子继续思考。
管程
为什么要引入管程
信号量机制存在的问题:编写程序困难、易出错
能不能设计一种机制,不用关注P、V操作,让写代码变得更轻松?
解决信号量机制编程麻烦、易出错的问题
管程的定义和基本特征
管程是一种特殊的软件模块,有这些部分组成:
1.局部于管程的共享数据结构说明;
2.对该数据结构进行操作的一组过程;
3.对局部于管程的共享数据设置初始值的语句;
4.管程有一个名字
1.局部于管程的共享数据结构说明;
2.对该数据结构进行操作的一组过程;
3.对局部于管程的共享数据设置初始值的语句;
4.管程有一个名字
管程的基本特征:
各外部进程/线程只能通过管程提供的特定“入口”才能访问共享数据
每次仅允许一个进程在管程内执行某个内部过程。
各外部进程/线程只能通过管程提供的特定“入口”才能访问共享数据
每次仅允许一个进程在管程内执行某个内部过程。
其实就是利用的封装的思想,将操作封装成一个函数。
补充
各进程必须互斥访问管程的特性是由编译器实现的
可在管程中设置条件变量及等待/唤醒操作以解决同步问题
死锁
概念
什么是死锁
各进程互相等待对方手里的资源,导致各进程都阻塞,无法向前推进
死锁、饥饿、死循环的区别
共同点:都是进程无法顺利向前推进的现象(故意设计的死循环除外)
死锁:至少是两个进程一起死锁,死锁进程处于阻塞态
饥饿:可以只有一个进程饥饿,饥饿进程可能阻塞也可能就绪
死循环,可能只有一个进程发生死循环,死循环的进程可上处理机
死锁和饥饿式操作系统要解决的问题,死循环是程序原要解决的问题
死锁产生的必要条件
互斥条件
对必须互斥使用的资源的争抢才会导致死锁
不可剥夺条件
进程保持的资源只能主动释放,不可强行剥夺
请求和保持条件
保持着某些资源不放的同时,请求别的资源
循环等待条件
存在一种进程资源的循环等待
循环等待未必死锁,死锁一定有循环等待
什么时候会发生死锁
对不可剥夺资源的不合理分配,可能会导致死锁
死锁的处理策略
预防死锁
破坏死锁产生的四个必要条件
避免死锁
避免系统进入不安全状态(银行家算法)
死锁的检测和解除
允许发生死锁,系统检测出死锁并解除
处理
不允许死锁发生
静态策略:预防死锁
破坏互斥条件
将临界资源改造为可共享使用的资源(如SPOOLing技术)
缺点:可行性不高,很多时候无法破坏互斥条件
破坏不剥夺条件
方案一:申请的资源得不到满足时,立即释放拥有的所有资源
方案二:申请的资源被其他进程占用时,由操作系统协助剥夺(考虑优先级)
缺点:实现复杂;剥夺资源可能导致部分工作失效;
反复申请和释放资源导致系统开销大;可能导致饥饿
反复申请和释放资源导致系统开销大;可能导致饥饿
破坏请求和保持条件
运行前分配好所有需要的资源,之后一直保持
缺点:资源利用率低;可能导致饥饿
破坏循环等待条件
给资源编号,必须按编号从小到大的顺序申请资源
缺点:不方便增加设备;会导致资源浪费;用户编程麻烦
动态策略:避免死锁
什么时安全序列
所谓安全序列,就是指如果系统按照这种序列分配资源,则每个进程都能顺利完成。只要找到一个安全序列,系统就是安全状态。当然,安全序列可能有多个。
什么时系统的不安全状态,与死锁有何联系
如果分配的资源之后,系统中找不出任何一个安全序列,系统就进入了不安全状态。这就意味着之后可能所有进程都无法顺利地执行下去。当然,如果有进程提前归还了一些资源,那系统也有可能重新回到安全状态,不过在分配资源之前总是要考虑到最坏的情况。
如果系统处于安全状态,就一定不会发生死锁。如果系统进入不安全状态,就可能发生死锁(处于不安全状态未必就是发生了死锁,但发生死锁一定处于不安全状态)
因此可以在资源分配之前先判断这次分配是否会导致系统进入不安全状态,一次决定是否答应 资源的分配请求。这也是“银行家算法”的核心思想。
如何避免系统进入不安全状态——银行家算法
核心思想
在进程提出资源申请时,先预判此次分配是否会导致系统进入不安全状态。如果会进入不安全状态,就暂时不答应这次请求,让该进程先阻塞等待。
数据结构
长度为m的一组数组Available表示还有多少可用资源
n*m矩阵max表示各进程对资源的最大需求数
n*m矩阵Allocation表示已经给进程分配了多少资源
Max-Allocation=Need矩阵表示各进程最多还需要多少资源
用长度为m的一位数组Request表示进程此次申请的各种资源数
n*m矩阵max表示各进程对资源的最大需求数
n*m矩阵Allocation表示已经给进程分配了多少资源
Max-Allocation=Need矩阵表示各进程最多还需要多少资源
用长度为m的一位数组Request表示进程此次申请的各种资源数
步骤
1.检查此次申请是否超过了之前声明的最大需求数
2.检查此时系统剩余的可用资源是否还能满足这次请求
3.尝试着分配,更改各数据结构
4.用安全性算法检查此次分配是否会导致系统进入不安全状态
2.检查此时系统剩余的可用资源是否还能满足这次请求
3.尝试着分配,更改各数据结构
4.用安全性算法检查此次分配是否会导致系统进入不安全状态
安全性算法步骤
检查当前的剩余可用资源是否能满足某个进程的最大需求,如果可以,九八该进程加入安全序列,并把该进程持有的资源全部回收。
不断重复上诉过程,看最终是否能让所有进程都加入安全序列
允许死锁发生
死锁的检测和解除
如何检测
数据结构:资源分配图
两种结点
进程节点
资源节点
两种边
进程结点->资源结点(请求边)
资源结点->进程结点(分配边)
死锁检测算法
依次消除与不阻塞进程相连的边,直到无边可消
注:所谓不阻塞进程是指其申请的资源数还足够的进程
死锁定理:若资源分配图是不可完全简化的,说明发生了死锁
如何解除
资源剥夺法
挂起(暂时放在外存上)某些死锁进程,并抢占它的资源,将这些资源分配给其他的死锁进程。但应房子被挂起的进程长时间得不到资源而饥饿。
撤销进程法(终止进程法)
强制撤销部分、甚至全部死锁进程,并剥夺这些进程的资源。优点是实现简单,但所付出的代价可能会很大。因为有些进程可能已经运行了很长时间,一旦被终止可谓是功亏一篑,还得从头再来。
进程回退法
让一个或多个死锁进程回退到足以避免死锁的地步。这就要求系统要记录进程的历史信息,设置还原点
进程实体组成
PCB
进程描述信息
进程标识符PID
用户标识符UID
进程控制和管理信息
CPU、磁盘、网络流量使用情况统计
进程当前状态:就绪态/阻塞太/运行态
进程分配清单
正在使用哪些文件
正在使用哪些内存区域
正在使用哪些I/O设备
处理机相关信息
如PSW\PC等等各种寄存器的值,用于实现进程切换
操作系统对进程进行管理工作所需的信息都存在PCB中
程序段
程序的代码(指令序列)
数据段
运行过程中产生的各种数据(如:程序中定义的变量)
程序段、数据段、PCB三部分组成了进程实体(进程映像)
注意:PCB是进程存在的唯一标志。
注意:一个程序运行多次会对应多个进程,比如DNF双开,会对应两个不同的进程,它们的PCB、数据段各不相同,但是程序段的内容都是相同的。
定义
引入了进程实体的概念后,可以把进程定义为:进程是进程实体的运行过程,是系统进行资源分配和调度的一个独立单位。
进程的特征
动态性
进程是程序的一次执行过程,是动态地产生、变化和消亡的
并发行
内存中有多个进程实体,各进程可以并发执行
独立性
进程是能独立运行、独立获得资源、独立接收调度的基本单位
异步性
各进程按各自独立的、不可预知的速度向前推进,操作系统要提供“进程同步机制”来解决异步问题
结构性
每个进程都会配置一个PCB,从结构上看,进程由数据段、程序段、PCB组成
状态与转换
状态
运行状态
如果一个CPU此时正在CPU上运行,那么这个进程就处于"运行态"
就绪状态
当进程创建完成后,便进入“就绪态”,处于就绪态的进程已经具备运行条件,但由于没有空闲CPU,就暂时不能运行
阻塞状态(等待态)
在成勋运行的过程中,可能会请求等待某个时间的发生(如等待某种系统资源的分配,或者等待其他进程的响应)。在这个事件发生之前,进程无法继续向下执行,此时操作系统会让这个进程下CPU,并让它进入“阻塞态”。当CPU空闲时,有会选择另一个“就就绪态”进程上CPU运行。
创建状态(新建态)
进程正在被创建时,它的状态为“创建态”,在这个阶段操作系统会为进程分配资源、初始化PCB
终止状态(结束态)
一个进程可以执行exit系统调用,请求操作系统终止该进程。此时进程会进入“终止态”,操作系统会让该进程下CPU,并回收内存空间等资源,最后还要回收该进程的PCB。
进程PCB中,会有一个变量state来标识进程的当前状态。如:1表示创建、2表示就绪、3表示运行
状态间的转换
就绪态->运行态
进程被调度
运行态->就绪态
时间片到,或者CPU被其他高优先级的进程抢占
运行态->阻塞态
等待系统资源分配,或等待某件事件发生(主动行为)
阻塞态->就绪态
资源分配到为,等待的事件发生(被动行为)
创建态->就绪态
系统完成创建进程的相关工作
运行态->终止态
进程运行结束,或运行过程中遇到不可修复的错误。
进程的组织方式(各个进程PCB的组织方式)
链式方式
按照进程状态将PCB分为多个队列
操作系统有指向各个队列的指针
索引方式
根据进程状态的不同,简历几张索引表
操作系统持有指向哥哥索引表的指针
线程
比如使用QQ,如果既想视频聊天又想文字聊天,没有线程的话只能使用多个进程的方式。但是多个QQ进程资源应该怎么共享成了问题。由于进程是资源分配的基本单位,为了能让视频聊天和文字聊天同时运行,CPU要并发地执行。在这种情况下,进程是调度的基本单位。并且由于分为了两个进程,这两个进程间的资源是不共享的。
同时,如果视频聊天进程想要使用文字聊天进程的一些资源,就需要进行切换进程,需要保存/回复进程的运行环境,还需要切换内存地址空间(更新块表、更新缓存)开销很大。
同时,如果视频聊天进程想要使用文字聊天进程的一些资源,就需要进行切换进程,需要保存/回复进程的运行环境,还需要切换内存地址空间(更新块表、更新缓存)开销很大。
引入了线程之后,一个进程之中可以包含多个线程,而不同的线程可以执行不同的代码序列。比如上述的视频聊天与文字聊天,就可以由两个线程对应两套代码序列来执行。引入线程后,线程是CPU调度的基本单位。但是,进程依旧是资源分配的基本单位,从属于同一个进程的各个线程共享进程的资源。这样就可以解决上述问题,两个线程共享资源。
进程间并发,开销比较大,线程间并发,开销比较小
引入线程级之后,并发带来的系统开销降低,系统并发性提升
对上述的总结
引入线程前,进程既是资源分配的基本单位,也是调度的基本单位。
引入线程之后,进程是资源分配的基本单位,线程是调度的基本单位,线程也有运行态、就绪态、阻塞态。(实现并发的)系统开销降低。
在多CPU环境下,各个线程也可以分派到不同的CPU上并行地执行
线程的重要特点
同一进程的各线程共享进程所拥有的资源
统一进程的线程切换不会导致进程切换
线程的实现方式
用户级线程
历史背景:早期的操作系统(如:早期Unix)只支持进程,不支持线程。当时的“线程”是由县城库来实现的
很多编程语言提供了强大的线程库,可以实现线程的创建、销毁、调度等功能
用户级线程是指从用户视角能看的到的线程,由线程库实现
1.线程的管理工作是由谁来完成的?
用户级线程的管理工作是应用程序通过线程库来完成的,所有的线程管理工作都由应用程序负责(包括线程切换)
2.线程切换是否需要CPU从用户态变为内核态?
用户级线程中,在用户态就能实现线程切换,并不用CPU变态,无需操作系统干预
3.操作系统是否能意识到用户级线程的存在?
在用户看来,是有多个线程。但是在操作系统内核看来,并不能意识到线程的存在。“用户级线程”就是“从用户视角能看到的线程”
4.优点和缺点
优点
用户级线程的切换在用户空间即可完成,不需要切换到核心态,线程管理的系统开销小,效率高
缺点
当一个用户级线程被阻塞后,整个进程(其他所有线程)都会被阻塞,并发度不高。多个线程不可能在多核处理机上并发运行。
内核级线程
从操作系统视角看到的线程,由操作系统实现(内核级线程才是处理机分配的单位)
1.线程的管理工作是由谁来完成的?
操作系统
2.线程切换是否需要CPU从用户态变为内核态?
线程调度、切换等工作都是由内核负责,因此内核级线程的切换必须在核心态下才能完成
3.操作系统是否能意识到用户级线程的存在?
操作系统会为每个内核级线程建立相应的TCB(线程控制块),通过TCB对线程进行管理。“内核级线程”就是“从操作系统内核视角能看到的线程”
4.优点和缺点
优点
当一个线程被阻塞后,别的线程还可以继续执行,并发能力强,多线程刻在多核处理机上并行执行。
缺点
一个用户进程会占用多个内核级线程,线程切换由操作系统内核完成,需要切换到核心态,因此线程管理的成本高、开销大
组合方式
上述两种方式的结合
多线程模型
一对一模型
一个用户级线程映射到一个内核级线程。每个用户进程有与用户级线程同数量的内核级线程
优点:当一个线程被阻塞后,别的线程还可以继续执行,并发能力强。多线程可在多核处理机上并行执行。
缺点:一个用户进程会占用多个内核级线程,线程切换由操作系统内核完成,需要切换到核心态,因此线程管理的成本高,开销大
多对一模型
多个用户级线程映射到一个内核级线程。且一个进程只被分配一个内核级线程
优点:用户级线程的切换在用户空间即可完成,不需要切换到核心态,线程管理的系统开销小,效率高
缺点:当一个用户级线程被阻塞后,整个进程都会被阻塞。多个线程不可再多核处理机上并行运行
重点:操作系统只“看得见”内核级线程,因此只有内核级线程才是处理机分配的单位
多对多模型
n用户级线程映射到m个内核级线程(n>=m)。每个用户进程对应m个内核级线程
克服了多对一模型并发度不高的缺点(一个阻塞全体阻塞),又克服了一对一模型中一个用户进程占用太多内核级线程,开销太大的缺点
集上述二者之长
一些概念的进一步理解
用户级线程是“代码逻辑”的载体
内核级线程是“运行机会”的载体
内核级线程才是处理机分配的单位。例如:多核CPU环境下,左边这个进程最多能分配两个核
一段“代码逻辑”只有获得了“运行机会”才能被CPU执行
内核级线程中可以运行任意一个有映射关系的用户级线程代码,只有两个内核级线程中正在运行的代码逻辑都阻塞时,这个进程才会阻塞
调度算法
先来先服务(FCFS)
算法思想
主要从“公平”的角度考虑(类似排队买东西)
算法规则
按照作业/进程到达的先后顺序进行服务
用于作业/进程调度
用于作业调度,考虑的是哪个作业先到达后备队列;用于进程调度时,考虑的是哪个进程先到达就绪队列
是否可抢占?
非抢占式的算法
EG:各进程到达就绪队列的时间、需要的运行时间如下表所示。使用FCFS,计算各进程的等待时间、平均等待时间、周转时间、平均周转时间、带权周转时间、平均带权周转时间。
EG答案:
优缺点
优点
公平、算法实现简单
缺点
排在长作业(进程)后面的段作业需要等待很长时间,带权周转时间很大,对段作业来说用户体验不好。即FCFS算法对长作业有利,对段作业不利
是否会导致饥饿
不会,一直等的话前面的进程肯定会被处理完的
端作业优先(SJF)
算法思想
追求最少的平均等待时间,最少的平均周转时间、最少的平均带权周转时间
算法规则
最短的作业/进程优先得到服务(所谓最短,是指要求服务时间最短)
用于作业/进程调度
既可用于作业调度,也可用于进程调度。用于进程调度时称为“短进程优先(SPF)算法”
是否可抢占?
SJF与SPF是非抢占式的算法,但是也有抢占式的版本——最短剩余时间优先算法(SRTN)
EG:各进程到达就绪队列的时间、需要的运行时间如下表所示。使用SPF,计算各进程的等待时间、平均等待时间、周转时间、平均周转时间、带权周转时间、平均带权周转时间。
此为非抢占式SPF
采用抢占式SRTN(又称“最短剩余作业优先”)看图的时候放大看,图太大了
注意几个小细节
1.题目中未标明,所提到的“短作业/进程优先”默认是非抢占式的
2.在所有进程同时可运行时,SJF的平均等待时间、平均周转时间最少,或者说,在所有进程都几乎同时到达时,采用SJF算法的平均等大时间、平均周转时间最少
3.严格来说,SJF的平均等待时间、平均周转时间并不一定最少,但相比于其他算法(如FCFS),SJF依然可以获得较少的平均等待时间、平均周转时间
4.有时题目中可能会说SJF的平均等待、周转时间最短,遇到这种看其他三个选项
5.有时候概念和题目对不上,那就凭做题数量吧
优缺点
优点
"最短的"平均等待时间、平均周转时间
缺点
不公平。对短作业有利,对长作业不利。另外,作业/进程的运行是由用户提供的,并不一定真实,不一定能做到真正的短作业优先
是否会导致饥饿
会。如果一直有短作业/进程到来,可能会使长作业/进程长时间得不到服务,产生饥饿。如果一直得不到服务,则称为饿死。
理解上述两种(FCFS)与(SJF)
FCFS对长作业友好,对短作业不友好
SJF对段作业友好,对长作业不友好
高相应比优先(HRRN)
算法思想
既要考虑到作业/进程的等待时间又要考虑到要求服务的和时间
算法规则
在每次调度时先计算各个作业/进程的响应比,选择响应比最高的作业/进程为其服务
响应比=(等待时间+要求服务时间)/要求服务时间
响应比>=1
用于作业/进程调度
均可
是否可抢占?
非抢占式
非抢占式的算法,因此只用当前运行的作业/进程主动放弃处理机时,才需要调度,才需要计算响应比
EG:同上,使用HRRN,计算结果略,有甘特图一切OK
优缺点
综合考虑了等待时间和运行时间(要求服务时间)
等待时间相同时,要求服务时间短的优先(SJF优点)
要求服务时间相同时,等待时间长的优先(FCFS的优点)
对于长作业来说,随着等待时间越来越就,其相应比也会越来越大,从而避免了长作业饥饿的问题
是否会导致饥饿
否
对前几种调度算法的总结
对上述的简单总结,还有一些图片中不全,请对应上述描述
时间片轮转调度算法
算法思想
公平地、轮流地位各个进程服务,让每个进程在一定时间间隔内都可以得到响应
算法规则
按照各进程到达就绪队列的顺序,轮流让各个进程执行ige时间片(如100ms)。若进程未在一个时间片内执行完,则剥夺处理机,将进程重新放到就绪队列队尾重新排队
用于作业/进程调度
用于进程调度(只有作业放入内存建立了相应的进程后,才能被分配处理时间片)
是否可抢占?
若进程未能在时间片内运行完,将被强行剥夺处理机使用权,因此时间品论转调度算法属于抢占式的算法,由时钟装置发出时钟中断来通知CPU时间片已到
EG:如图 最后图上面的是
优缺点
优点
公平、相应快,适用于分时操作系统
缺点
由于高频率的进程切换,因此有一定开销;不区分任务的紧急程度
是否会导致饥饿
否
优先级调度算法
算法思想
随着计算机的发展,特别是实时操作系统的出现,越来越多的应用场景需要根据任务的紧急程度来决定处理顺序
算法规则
每个作业/进程都有各自的优先级,调度时选择优先级最高的作业/进程
用于作业/进程调度
既可用于作业调度,也可用于进程调度。甚至还可用于I/O调度中
是否可抢占?
抢占式、非抢占式都有。做题时的区别在于:非抢占式只需进程主动放弃处理机时进行调度即可,而抢占式还需要在就绪队列变化时,检查是否会发生抢占
抢占例题
非抢占例题
优缺点
优点
用优先级区分紧急程度、重要程度,适用于实时操作系统,可以灵活地调整对各种作业/进程的偏好程度
缺点
若源源不断地有更高优先级进程到来,则可能导致饥饿
是否会导致饥饿
会
补充
就绪队列未必只有一个,可以按照不同的优先级来组织。另外,也可以把优先级高的进程排在更靠近队头的位置
根据优先级是否可以动态改变,可将优先级分为动态优先级和静态优先级两种
静态优先级
创建进程后确定,之后一直不变
动态优先级
创建进程时有一个初始值,之后会根据情况动态地调整优先级
如何合理地设置各类进程的优先级
系统进程优先级高于用户进程
前台进程优先级高于后台进程
操作系统更偏好I/O型进程(或称I/O繁忙型进程)
注:与I/O型进程相对应的是计算机进程(CPU繁忙型进程)
如果采用动态优先级技术,应该什么时候调整优先级?
可以从追求公平、提升资源利用率等角度考虑
如果某进程在就绪队列中等待了很长时间,则可以适当提升其优先级
如果一个进程占用处理机运行了很长时间,则可以适当降低其优先级
如果一个进程频繁地进行I/O操作,则可适当提升其优先级
思考
FCFS算法的优点是公平
SJF算法的优点是能尽快处理完段作业。平均等待、平均周转时间等参数很优秀
时间片轮转调度算法可以让各个进程得到及时的响应
优先级调度算法可以灵活地调整各种进程被服务的机会
能否集上述之长?
如下多级反馈队列调度算法
如下多级反馈队列调度算法
多级反馈队列调度算法
算法思想
对其他调度算法的这种权衡
算法规则
1,设置多级就绪队列,各级队列优先级从高到低,时间片从小到大
2.新进程到达时先进入第一级队列,按FCFS原则排队等待被分配时间片,若用完时间片进程还未结束,则进程进入下一级队列队尾。如果此时已经是最下级的队列,则重新放回该队列队尾
3.只有第K级队列为空时,才会为K+1级对头的进程分配时间片
用于作业/进程调度
用于进程调度
是否可抢占?
抢占式的算法。在K级队列的进程运行过程中,若上级的队列(1~K-1级)中进入了一个新进程,则由于新进程处于优先级更高的队列中,因此新进程会抢占处理机,原来运行的进程放回K级队列队尾。
优缺点
对各类进程相对公平(FCFS的优点);每个新到达的进程都可以很快就得到响应(RR的优点);短进程只用较少的时间就可以完成(SPF的优点);不必实现估计进程的运行时间(避免用户作假);可灵活地调整对各类进程的偏好程度,比如CPU密集型进程、I/O密集型进程(拓展:可以将因I/O而阻塞的进程重新放回原队列,这样I/O型进程就可以保持较高优先级)
是否会导致饥饿
会。如果有远远不断的短进程进来的话
后三种调度算法的对比
比起早期的批处理系统来说,由于计算机造价大幅降低,因此之后出现的交互式操作系统(包括分时操作系统、实时操作系统等)更注重系统的响应时间、公平性、平衡性等指标。而这集中算法恰好也能较好的满足交互式系统的需求,因此后三种算法适用于交互性系统。(比如UNIX使用的就是多级反馈队列调度算法)
0 条评论
下一页