操作系统笔记:进程管理教程
进程管理
程序:指令序列
系统为每个运行的程序配置一个数据结构,称为进程控制块(即PCB,是进程存在的唯一标志,创建进程实质上是创建进程实体中的PCB、撤销进程实质上是撤销进程实体中的PCB),用来描述进程的各种信息(如程序代码存放位置)。这样设计可以实现:内存中同时放入多道程序时,操作系可以找到各程序的存放位置。
进程的组成:
PCB(进程的管理者-操作系统,所需的数据)、
程序段(存放要执行的代码)、
数据段(存放程序运行过程中处理的各种数据)
PCB的组成:
1)进程描述信息
进程标识符PID(进程创建时,操作系统为该进程分配唯一的ID)
用户标识符UID
2)进程控制和管理信息
进程当前状态
进程优先级
3)资源分配清单
程序段指针
数据段指针
键盘
鼠标
4)处理机相关信息
各种寄存器值
进程的组织、特征:
进程的组成指的是进程内部由哪些部分构成
进程的组织讨论的是多个进程之间的组织方式
组织方式:
1)链接方式:按照进程状态将PCB分为多个队列,操作系统持有指向各个队列的指针
2)索引方式:按照进程状态的不同,建立几张索引表,操作系统持有指向各个索引表的指针
进程特征:
- 动态性:进程是程序的一次执行过程,是动态的产生,变化,消亡的
- 并发性:内存中由多个进程实体,各进程可并发执行
- 独立性:进程是独立运行、获得资源、接受调度的基本单位
- 异步性:各进程各自独立、不可预知的向前推进,系统提供进程同步机制解决异步问题
- 结构性:每个进程都会配置一个PCB
进程的状态与转换
进程状态:
三种基本状态:
- 运行态:占有CPU,并在CPU上运行
- 就绪态:已经具备运行条件,但是没有空闲CPU,而暂时不能运行
- 阻塞态(等待态):因等待某一事件而暂时不能运行
另外两种状态:
- 创建态(新建态):进程正在被创建,操作系统为进程分配资源,初始化PCB
- 终止态(结束态):进程正在从系统中撤销,操作系统会回收进程拥有的资源,撤销PCB
状态转换:
进程控制
对系统中的所有进程实施有效管理,它具有创建新进程、撤销已有进程、实现进程状态转化等功能。
实现进程控制:用原语实现,是一种特殊的程序,他的执行具有原子性,运行过程一气呵成、不可中断(如果没有原子性,不能一气呵成,可能会导致系统中 某些关键数据信息不一致)
进程控制原语的工作任务:
- 更新PCB中的信息,如修改进程状态标志、将运行状态保存到PCB、从PCB恢复运行环境
1)所有的进程控制原语一定都会修改进程状态标志
2)剥夺当前运行进程的CPU使用权必然需要保存其运行环境
3)某进程开始运行前必然要恢复其运行环境
- 将PCB插入合适的队列
- 分配/回收资源
进程通信
即进程之间的信息交换。因为进程是分配系统资源的单位,因此各进程拥有的内存地址空间相互独立。
为了保证安全,一个进程不能直接访问另一个进程的地址空间。
- 共享储存
- 消息传递
- 管道通信
共享储存
管道通信
消息传递
线程、多线程模型
有的进程可能需要同时处理很多事,传统的进程只能串行的执行一系列程序。为此,引入线程来增加并发度
线程是程序执行的最小单位。可以理解为“轻量级进程”
线程的属性
线程的实现方式
多线程模型
处理机调度
调度:确定某种规则来决定处理任务的顺序
处理机调度:进程数量多于处理机个数,不可能同时并行处理各个进程。因此,处理机调度就是从就绪队列中按照一定的算法选择一个进程并将处理机分配给他
调度的三个层次
- 高级调度(作业调度):
按一定原则从外存上处于后备队列的作业中挑选一个或者多个作业,给他们分配内存等必要资源,并建立相应的进程(建立PCB),以使他们获得竞争处理机的权利
辅存(外存)与 内存之间的调度,每个作业只调入一次,调出一次。作业调入时会建立相应的PCB,作业调出时才撤销PCB
- 中级调度(内存调度):
引入虚拟内存后,可将暂时不能运行的进程调到外存等待。等他重新具备了运行条件且内存又稍有空闲时,再重新调入内存,这么做可以提高内存利用率和系统吞吐量。
暂时调到外存等待的进程状态为挂起状态,而PCB并不会一起调到外存,而是常驻内存,因为操作系统得通过内存中的PCB保持对各个进程的监控、管理。被挂起的进程PCB会被放到挂起队列中
- 低级调度(进程调度):
按照某种方法和策略从就绪队列中选取一个进程,将处理机分配给他。进程调度是操作系统中最基本的一种调度,使用频率很高,一般几十毫秒一次。
三层调度的联系、对比
进程七状态模型
进程调度的时机、切换与过程、方式
时机
- 当前进程主动放弃处理机
1)进程正常终止
2)运行过程中发生异常而终止
3)进程主动请求阻塞(如等待I/O)
- 当前进程被动放弃处理机
1)分给进程的时间片用完
2)又更紧急的事情处理(如I/O中断)
3)有更高优先级的进程进入就绪队列
切换与过程
进程切换:一个进程让出处理机,由另一个进程占用处理机的过程
切换过程:
- 对原来运行进程的各种数据的保存
- 对新的进程的各种数据的恢复
方式
非剥夺调度方式
剥夺调度方式
调度算法的评价指标
CPU利用率
cpu忙碌的时间占总时间的比例
系统吞吐量
单位时间完成的任务
周转时间
作业被提交给系统到作业完成为止的这段时间间隔
包括四部分:
- 作业在外存后备队列上等待作业调度(高级调度)的时间
- 进程在就绪队列上等待进程调度(低级调度)的时间
- 进程在CPU上执行的时间
- 进程等待I/O操作完成的时间
等待时间
响应时间
从用户提交请求到首次产生响应所用时间
调度算法
先来先服务
考虑等待时间最长(即最早到达)的作业,为其服务
短作业优先
选择执行时间最短作业为其服务
高响应比优先
响应比=(等待时间+要求服务时间)/ 要求服务时间
时间片轮转调度算法
时间片的选择:
太大:退化为先来先服务算法
太小:频繁切换进程,开销大
优先级调度算法
多级反馈队列算法
进程同步
同步又称直接制约关系,它是指为完成某种任务而建立的两个或者多个进程,这些进程因为需要在某些位置上协调他们的工作次序而产生的制约关系。进程间的直接制约关系就是源于他们之间的相互合作
eg:进程之间通过管道通信是,写进程和读进程并发执行。并发必然导致异步性。因此,这两个操作的先后顺序是不确定的。但是实际应用中,必然是按照“写数据->读数据”的顺序来执行
进程互斥
资源共享方式:
1.互斥共享方式(系统中某些资源,虽然可以提供给多个进程使用,但一个时间段内只允许一个进程访问该资源)
2.同时共享方式(系统内的某些资源,允许一个时间段内由多个进程“同时”对他们进行访问)
临界资源:一个时间段内只允许一个进程使用的资源。
举例:摄像头、打印机、内存缓冲区
进程互斥定义:
当一个进程访问某临界资源时,另一个想要去访问该临界资源的进程必须等待。当前访问临界资源的进程访问结束,释放该资源后,另一个进程才能去访问临界资源
进程互斥基本原则:
进程互斥软件实现方法
单标志法
两个算法在访问完临界区后会把使用临界区的权限交给另外一个进程。也就是说每个进程进入临界区的权限只能被另一个进程赋予。
例子:
双标志检查法
用数组记录各进程想要进入临界区的意愿
先“检查”,后“上锁”
例子:
双标志后检查法
在双标志检查法的基础上修改
先“上锁”,后“检查”
例子:
Peterson算法
在双标志后检查法的基础上,增加判断是否谦让
进程互斥硬件实现方法
中断屏蔽方法
TestAndSet指令
Swap指令
信号量机制
用户进程可以通过使用操作系统提供的一对原语来对信号量进行操作,从而很方便的实现了进程的互斥、进程同步。
一对原语:wait(S)、signal(S)原语,常简称为P、V操作
信号量其实就是一个变量,可以用一个信号量来表示系统中某种资源的数量。
整形信号量
用一个整数型变量作为信号量,用来表示系统中某种资源的数量
与整型变量的区别:对信号量的操作只有三种,初始化、P、V操作
存在问题:不满足让权等待,会发生忙等
记录型信号量
为解决整形信号量会出现忙等现象而出现
信号量机制实现进程互斥
- 分析并发过程关键活动,划分临界区(如对临界资源打印机的访问应放在临界区)
- 设置互斥信号量mutex
- 在临界区之前执行P(mutex)
- 在临界区之后执行V(mutex)
注意:对不同临界资源需要设置不同互斥信号量;P、V操作必须成对出现
信号量机制实现进程同步
- 分析什么地方需要实现“同步关系”,即保证“一前一后”执行的两个操作
- 设置同步信号量,初始为0
- 在“前操作”之后执行V(S)
- 在“后操作”之前执行P(S)
信号量机制实现前驱关系
前驱关系本质上就是多对同步关系
- 分析问题,画出前驱图
- 为每一对前驱关系设置一堆同步信号量
- 每个“前操作”之后执行V(S)
- 每个“后操作”之前执行V(S)
生产者-消费者问题
理清关系:
- 两对同步关系:消费者等待生产者生产;生产者等待消费者消费
- 一对互斥关系:缓冲区是临界资源
实现互斥操作,必须在同步操作之后。否则会导致死锁
读者-写者问题
读者-读者不互斥
读者-写者互斥
写者-写者互斥
管程
一种高级同步机制
组成
- 局部于管程的共享数据结构说明
- 对该数据结构进行操作的一组过程
- 对局部于管程的共享数据设置初始值的语句
- 管程有一个名字
基本特征
- 局部于管程的数据只能被局部于管程的过程所访问(特定入口访问)
- 一个进程只有通过调用管程内的过程才能进入管程访问共享数据
- 每次仅允许一个进程在管程内执行某个过程
死锁
死锁:并发环境下,各进程因竞争资源而造成的一种互相等待对方手里的资源,导致各进程都阻塞,都无法向前推进的现象。
饥饿:由于长期得不到想要的资源,某进程无法向前推进的现象
死循环:某进程执行过程中一直跳不出某个循环的现象
产生条件
- 互斥条件:必须争夺使用的资源,如打印机设备、哲学家的筷子等。而像内存、扬声器这种可以同时给多个进程使用的资源是不会导致死锁的
- 不剥夺条件:进程所获得的资源在未使用完之前,不能由其他进程强行夺走,只能主动释放
- 请求和保持条件:进程已经保持了一个资源,但又提出了新的资源请求,而这个资源又被其他进程占有,此时请求进程被阻塞,但又对自己已有的资源保持不放
- 循环等待条件:存在一种进程资源的循环等待链,链中的每一个进程已获得的资源同时被下一个进程所请求
死锁处理策略
- 预防死锁:破坏死锁产生的四个必要条件中的一个或几个
- 避免死锁:用某种方法防止系统进入不安全状态,从而避免死锁
- 死锁的检测和解除:允许死锁的发生。不过操作系统会检测出死锁的发生,然后采取某种措施解除死锁
预防死锁
破坏死锁的四个产生条件
破坏互斥条件:
把只能互斥使用的资源改造为允许共享使用,如SPOOLing技术。
缺点:并不是所有资源都可以改造成可共享使用的资源,并且为了系统安全,很多地方还必须得保护这种互斥性。因此,很多时候都无法破坏互斥条件
破坏不剥夺条件:
方案1:当某个进程请求新的资源得不到满足时,它必须立即释放保持的所有资源,待以后需要时再重新申请。也就是说,某些资源尚未使用完,也需要主动释放
方案2:当某个进程需要的资源被其他进程所占有的时候,可以由操作系统协助,将想要的资源强行剥夺。这种方方法一般需要考虑各进程的优先级
缺点:
破坏请求和保持条件
采用静态分配方法,在进程允许前,一次申请完它所需的全部资源,在它的资源未满足前不让它投入运行。一旦运行后,该资源就一直归它所有。所以就避免了该进程请求其他资源
缺点:
某些资源可能只需要用很短的时间,因此如果进程的整个运行期间都一直保持着所有的资源就会造成严重的资源浪费,资源利用率极低。另外,该方案也有可能导致某些进程饥饿
破坏循环等待条件
顺序资源分配法:首先给系统中的资源编号,规定每个进程必须按编号递增的顺序请求资源,同类资源(即编号相同的资源)一次申请完
原理分析:一个进程只有已占有小编号的资源时,才有资格申请更大编号的资源,已持有大编号资源的进程不可能逆向的回来申请小编号的资源,从而就不会产生循环等待的现象
缺点:
- 不方便增加新的设备,因为有可能需要重新分配所有的编号
- 进程实际使用的资源可能与编号递增顺序不一致,会导致资源浪费
- 必须按照规定次序申请资源,用户编程麻烦
避免死锁
安全序列
系统如果按照某种序列分配资源,则每个进程都能顺利完成。只需要找出一个安全序列,系统就是安全状态。安全序列可能会有多个
银行家算法
核心思想:在资源分配之前预先判断这次分配是否会导致系统进入不安全状态,以此决定是否答应资源分配请求
死锁的检测和解除
死锁的检测
用以检测系统状态,以确定系统中是否发生了死锁
- 用某种数据结构来保存资源的请求和分配信息 - 资源分配图
- 提供一种算法,利用上述信息检测系统是否已经进入死锁状态
如果能消除所有边,就称这个图是可完全简化的,此时一定没有发生死锁(相当于找到一个安全序列)。如果最终不能消除所有边,那么此时必然发生了死锁,最终还连着边的那些进程就是处于死锁状态的进程
死锁的解除
当认定系统中发生了死锁,利用该算法可将系统从死锁中解脱出来
- 资源剥夺法。挂起(暂时放到外存上)某些死锁进程,并抢占它的资源,将这些资源分配给其他死锁进程。但是应防止被挂起的进程长时间得不到资源而饥饿
- 撤销进程法。强制撤销部分、甚至全部死锁进程,并剥夺这些进程的资源
- 进程回退法。让一个或多个死锁进程回退到足以避免死锁的地步,这就要求系统要记录进程的历史信息,设置还原点