一. 进程控制
1. 什么是进程控制?
进程控制是进程管理中的最基本的功能,主要包括创建新进程、终止已完成的进程、将因发生异常情况而无法继续运行的进程置于阻塞状态、负责进程运行中的状态转换功能。
简单来说:进程控制就是要实现进程状态的转换
2. 如何实现进程控制呢?
3. 进程的切换需要修改PCB的内容,并放到相应的队列中去,假如没有修改PCB中的状态标志就把PCB放入到某个队列中去了,这种情况特别危险,怎么避免呢?
4. 进程控制原语做了哪些事情呢?
5. 进程创建
6. 进程终止
7. 进程的阻塞与唤醒
8. 进程的挂起和激活
9. 进程的切换
二. 进程通信
在网络环境的应用领域主流的进程通信实现机制:客户机-服务器系统
1. 什么是进程通信呢?
2. 共享存储
3. 管道通信
4. 消息传递
三. 处理机调度
1. 什么是调度
在多道程序系统中,调度的实质是一种资源分配。
处理机调度就是对处理机资源进行分配。
2. 处理机调度的层次
在多道批处理系统中,一个作业从提交到获得处理机执行,直至作业运行完毕,可能需要经历多级处理机调度
注:作业和进程的区别
(1). 高级调度
1. 什么是作业
作业(job):是一个比程序更为广泛的概念,他不仅包含了通常的程序和数据,而且还应配有一份作业说明书,系统根据说明书对程序的运行进行控制。在批处理系统中,是以作业为基本单位从外存调入内存
2. 作业里面含有什么?
- 程序
- 数据
- 作业说明书
- 作业控制块(Job control block,JCB)
3. 作业运行的三个阶段
- 收容阶段
- 运行阶段
- 完成阶段
4. 作业调度的主要任务
根据JCB中的信息,检查系统中的资源能否满足作业对资源的需求,以及按照一定的调度算法,从外存的后备队列选取某些作业调入内存,并为它们创建进程、分配资源。然后再将新创建的进程排在就绪队列上等待调度。
(2). 中级调度
(3). 低级调度
1. 进程调度的时机是什么?
用一个例题来解释:为什么进程在操作系统内核程序临界区中不能进行进程调度
2. 进程调度的方式
在有的操作系统中,只允许进程主动放弃处理机,而不允许进程在运行的时候被迫的倍剥夺资源。
有的操作系统中,进程可以主动的放弃处理机,当有更紧急的任务需要处理时,也会强行剥夺处理机(被动放弃)
这样我们可以根据当前运行的进程是否可以被强行剥夺处理机资源这个问题我们引出
进程调度的方式:
注:
- 非抢占方式
采用了非抢占调度方式之后,还会引起进程调度的因素就只有以下几种情况
非抢占方式不能用于分时和大多数实时操作系统
- 抢占方式
抢占不是任意的,而是有一定的规则
3. 进程切换的过程
既然选择了一个进程要为他分配处理机的话,我们怎么进行进程切换呢?
4. 进程调度实现机制
为了实现进程调度,在进程调度机制中,应具备如下三个基本部分:
- 排队器
- 分派器
- 上下文切换器
4. 三种层次的比较
3. 调度算法
1. 调度算法的评价指标
(1). CPU的利用率
(2). 系统吞吐量
(3). 周转时间
(4). 等待时间
(5). 响应时间
2. 调度算法举例①(早期批处理系统使用的算法,交互性差)
(1). 先来先服务(FCFS, First Come First Server)
举例:
(2). 短作业优先(SJF,Shortest Job Frist)
举例1:非抢占式短进程优先(SPF,Shortest Process Frist)
举例2:最短进程优先算法的抢占式版本是最短剩余时间优先(Shortest Remaining Time Next, SRTN)算法
短作业优先算法注意的小细节
(3). 高响应比优先(HRRN,Highest Response Ratio Next)
从FCFS和FJS两种算法来思考,得出一个新的算法
举例:
三种算法的比较
3. 调度算法举例②(适合用于交互式系统)
(1). 时间片轮转(RR, Round Robin)
举例1:时间片轮转调度算法(时间片为2)
举例1:时间片轮转调度算法(时间片为5)
注:时间轮转调度算法的时间片不能太大或太小
(2). 优先级调度算法
举例1:非抢占式优先级调度算法
举例2:抢占式优先级调度算法
注:补充一些知识
(3). 多级反馈队列(Multileved feedback queue)调度算法
举例:多级反馈队列调度算法的规则
三种算法总结:
四. 进程同步和进程互斥
1. 什么是进程同步
在OS中引入进程之后,一方面可以使系统中的多道程序并发执行,这不仅能有效的改善资源利用率,还可以显著提高系统吞吐量,但是另一方面却使系统变得更加复杂
如果不能采取有效措施,对多个进程的运行进行妥善管理,这些进程对系统资源的无序争夺对系统造成混乱。使每次处理结果都存在不确定性,即不可再现性
进程同步的目标:对多个进程在执行次序上进行协调,使并发执行的进程能按照一定规则共享系统资源,进行相互合作,使程序的执行具有可再现性
2. 什么是进程互斥
注:许多硬件资源如:打印机、磁带机等都属于临界资源,各进程间应采取互斥方式,实现对这种资源的共享
注:不论是硬件临界资源还是软件临界资源,多个进程必须互斥的对他进行访问
人们把在每个进程值访问临界资源的那段代码称为临界区
如果能够保证各进程互斥的进入临界区,就可以实现对临界资源的互斥访问
如果一个进程暂时不能进入临界区,那么该进程是否应该一直占着处理机?该进程有没有可能一直进不了临界区?
3. 如何实现进程互斥呢?
(1). 进程互斥的软件实现方法
方法一:单标志法
缺点:
方法二:双标志先检查法
缺点:
方法三:双标志后检查法
缺点:
方法四:Peterson算法
缺点:
(2). 进程互斥的硬件实现方法
方法一:中断屏蔽方法
方法二:Test and Set指令
方法三:Swap指令
4. 如何更好的实现进程同步和互斥呢?
1. 什么是信号量?
2. 有哪些信号量机制?
信号量机制主要有:整型信号量机制、记录型信号量机制、AND信号量机制、信号量集机制
而我们主要介绍以下两种:整型信号量机制、记录型信号量机制
(1). 整型信号量
(2). 记录型信号量
举例1:初始状态:
一开始CPU为进程P0服务:
之后CPU切换到P1进程,为P1进程服务:
然后CPU再为P2进程服务,此时没有打印机资源了,P2进程执行了block原语,进入等待队列
接下来,CPU转向了P3进程,为P3进程服务,同样在执行wait原语的时候,发现没有资源,主动执行block原语,进入等待队列队尾
然后CPU又转向了P0,为P0进行服务,P0使用完打印机之后,执行signal原语,在signal原语里面又执行力wakeup原语,用来唤醒等待队列队头的进程
P0进程执行完之后,CPU又为P2进程进行服务,P2就可以使用打印机资源,同时进行signal原语,唤醒P3进程
然后CPU又为P1进程服务,此时value加一之后大于0了,说明等待队列没有进程在等待了,所有就不需要执行wakeuo原语
最后CPU转到P3进程,为之服务,P3顺利执行到结束,系统回收打印机资源
总结:
(3). AND型信号量
(4). 信号量集机制
3. 如何使用信号量机制实现进程同步、互斥、前驱关系?
(1). 利用信号量实现进程互斥
(2). 利用信号量实现进程同步
(3). 利用信号量实现前驱关系
5. 经典进程同步、互斥问题
(1). 生产者消费者问题
当缓冲区当中有一个或者大于一个的空闲空间,此时就可以唤醒生产者进程,让他从阻塞态重新回到就绪队列
当消费者进程取空了缓冲区之后,消费者进程就会被阻塞
然后到生产者进程重新向缓冲区放数据的时候,消费者才会被唤醒,重新回到就绪队列
注:缓存区时临界资源,各进程必须互斥的访问
因为:如果我们系统中出现了两个生产者进程,此时生成者进程发现缓存区每个地方都是空的,可以进行放数据,一个生产者在某一个地方放数据
在并发的环境下,另一个生成者也在同样一个地方放数据,导致前者数据被后者数据覆盖的情况
如何用信号量机制(P、V操作)实现生产者、消费者进程的这些功能呢?
设置初始信号量
具体的代码实现
能否改变相邻P、V操作顺序呢?
注:生产者生产一个产品和消费者消费一个产品操作能否放到互斥信号量P、V操作之内?
逻辑上没有问题,从缓冲区取出一个产品,紧接着就使用产品
但是这就导致了临界区代码量变大,消费者在访问临界区就需要耗费更长的时间,若此时也有别的进程想要访问临界区的话,它是会被阻塞的,使得进程之间的并发度降低。
所以这两步代码不建议放到临界区之间
生产者消费者问题总结:
(2). 多生产者-多消费者问题
代码实现
可以不用互斥信号量吗?
结论:即使不设置专门的互斥变量mutex,也不会出现多个进程同时访问盘子的现象
原因在于:本题的缓冲区大小为1,在任何时刻,Apple、orange、plate三个同步信号量中最多只有一个,因此在任何时候,最多只有一个进程的P操作,不会被阻塞,并顺利的进入临界区
总结:
(3). 吸烟者问题
设置信号量
代码实现:
是否需要设置一个专门的互斥信号量?
缓存区大小为1,同一时刻,四个同步信号量中至多有一个值为1,不用设置互斥信号量总结:
(4). 读者-写者问题
如果两个写进程同时访问共享文件的话,两个写进程同时发现一块空闲空间,进而相继写入,会导致第二个写进程把第一个写进程数据覆盖了
问题分析
代码实现
解决方法:
此方法任然存在潜在问题:只要有读进程还在读,写进程就要一直阻塞等待,可能饿死,因此这种算法中,读进程是优先的解决方法:
总结:
(5). 哲学家进餐问题
方法一:
出现的问题:产生死锁
如何防止死锁的发生呢?
- 方案一:
- 方案二:
- 方案三:
- 代码实现
情况1:0号哲学家,拿了左边的筷子,此时若进程切换为2号,但2号在进行mutex操作时,会被阻塞,直到0号哲学家拿到右边的筷子,并进行V(mutex)之后,2号才会被激活,执行下面代码,拿起左边和右边筷子 - 情况2:一开始0号,拿起了左边和右边筷子正在吃饭,此时1号也想拿起筷子,没有被mutex阻塞,但是左边还没有筷子,会发生阻塞,此时调度为2号,但是2号会被mutex阻塞,即使2号两边都有筷子
- 情况3:一开0号拿来左边和右边的筷子进行吃饭,当调度为4号,4号拿起了左边的筷子,但是右边没有筷子,发生阻塞
因此这种方法并不能保证只有两边的筷子都可以使用时,才允许哲学家拿起筷子
总结:
5. 管程
(1). 为什么要引入管程
虽然信号量机制是一种既方便、又有效的进程同步机制,但每个要访问临界资源的进程都必须自备同步操作wait(S)、signal(S)。这就使得大量的同步操作分散在各个进程中,这不仅给系统的管理带来麻烦,还会因同步操作使用不当而导致系统死锁
(2). 管程的定义和基本特征
官方定义:代表共享资源的数据结构以及由对该共享资源结构实施操作的一组过程所组成的资源管理程序共同构成了一个操作系统的资源管理模块,称之为管程
Hansan为管程下定义:一个管程定义了一个数据结构和能为并发进程所执行的一组操作,这组操作能同步进程和改善管程中的数据结构
(3). 用管程解决生产者消费者问题
(4). Java 中类似于管程的机制
(5). 总结
6. 死锁
(1). 什么是死锁(Deadlock)
如果一组进程中的每一个进程都在等待仅由该组进程中的其他进程才能引发的事件,那么该组进程是死锁的
(2). 死锁、饥饿、死循环的区别
(3). 死锁产生的必要条件
(4). 什么时候会发生死锁
(5). 死锁的处理策略
1. 预防死锁
2. 避免死锁
找不到安全序列的例子
用代码实现银行家算法
银行家算法步骤
3. 死锁的检测和解除
总结: