4进程管理
死锁问题
设备分配形成环路
进程通信问题导致死锁
定义
各并发进程彼此互相等待对方所拥有的资源,且这些并发进程在得到对方的资源之前不会释放自己所拥有的资源。从而造成大家都想得到资源而又都得不到资源,各并发进程不能继续向前推进的状态。
起因
死锁的起因是并发进程的资源竞争。
根本原因:系统提供的资源个数少于并发进程所要求的该类资源数。
由于资源的有限性,不可能为所有要求资源的进程无限制地提供资源可以采用适当的资源分配算法,以达到消除死锁的目的。
产生的必要条件
- 互斥条件。
- 不剥夺条件。
- 部分分配。
- 环路条件。
只要使上述4个必要条件中的某一个不满足,则死锁就可以排除。
解决死锁的方法
预防 避免 检测与恢复
死锁预防
预防是采用某种策略,限制并发进程对资源的请求,从而使得,死锁的必要条件在系统执行的任何时间都不满足。
- 打破资源的互斥和不可剥夺这两个条件,例如允许进程同时访问某些资源等。
- 打破资源的部分分配这个死锁产生的必要条件。即预先分配各并发进程所需要的全部资源。
打破死锁环路条件
把资源分类按顺序排列,使进程在申请、保持资源时不形成环路。
如有m种资源,则列出R1<R2<…<Rm。若进程Pi保持了资源Ri,则它只能申请比Ri级别更高的资源Rj(Ri <Rj )。释放资源时必须是Rj先于Ri被释放,从而避免环路的产生。
缺点是限制了进程对资源的请求,而且对资源的分类编序也耗去一定的系统开销。
死锁避免
避免是指系统在分配资源时,根据资源的使用情况提前做出预测
,从而避免死锁的发生。
死锁避免可被称为动态预防
,因为系统采用动态分配资源,在分配过程中预测出,死锁发生的可能性并加以避免的方法。
死锁避免的一种基本模式是把进程分为多个步,进程的资源请求、使用与释放要依靠不同的步完成
死锁避免需要占去系统较大的开销
系统安全状态和进程安全序列,如:银行家算法避免死锁
死锁的检测和恢复
当进程进行资源请求时,死锁检测算法 检查并发进程组,是否构成资源的请求和保持环路
。
死锁的恢复办法:
- 终止各锁住进程,或按一定的顺序中止进程序列,直至已释放到有足够的资源来完成剩下的进程时为止
- 从被锁住进程强迫剥夺资源以解除死锁
在实际操作系统中大都使用检测与恢复法排除死锁。
线程的线程
为什么要引入线程?
进程是并发执行的程序 在执行过程中分配和管理资源的基本单位。
同一段程序,在不同的执行时间,是否属于不同的进程?
-
在许多情况下用户所要完成的任务具有相似的性质,
(相似的性质)
如WEB服务器处理不同用户的网页访问请求。
-
创建一个进程要花费较大的系统开销和占用较多的资源,如至少要消费一个PCB结构。
(创建一个进程成本较大)
-
进程上下文切换过程复杂,系统开销大。
(切换复杂)
引入线程:减少进程创建和切换开销,提高执行效率和节省资源。
基本概念
线程是进程的一部分
线程有时又被成为:轻权进程 或 轻量级进程
线程也是CPU调度的一个基本单位,
这个调度单位既可以由操作系统内核控制,也可以由用户程序控制
一个没有线程的进程可以被看作是单线程的,该进程所拥有的资源只为该线状执行过程服务
进程内有多个线程,则进程的执行过程不再是唯一现状的,
而是由多条线状执行过程组成:
线程与进程的区别
-
进程是资源分配的基本单位,所有与该进程有关的资源都被记录在进程控制块PCB中
-
线程与资源分配无关,它属于某一个进程,并与进程内的其他线程一起共享进程的资源
-
进程是抢占处理机的调度单位,拥有一个完整的虚拟地址空间。
-
同一进程内的不同线程共享同一地址空间。
-
线程控制表TCB保存的线程状态信息,比PCB表少得多。
-
同一进程内的线程切换减少了操作系统的开销时间。
进程的调度与切换都是由操作系统内核完成,而线程则既可由操作系统内核完成,也可以由用户程序进行。
变动的更多的是寄存器和栈
多线程与进程之间的关系
使用线程的优势:
- 在有
多个任务需要处理机处理时,减少处理机切换时间
; - 线程的创建和结束所需要的系统开销也比进程的创建和结束小得多。
线程的适用范围
并不是在所有的计算机系统中线程都是适用的。
最适合使用线程的系统是多处理机系统和网络系统或分布式系统。
在用户程序可以按功能划分为不同的小段时,单处理机系统也可因使用线程而简化程序的结构和提高执行效率。
几种典型的应用是:
- 服务器中的文件管理或通信控制。
- 前后台处理。
- 异步处理。程序中的两部分如果在执行上没有顺序规定,则这两部分程序可用线程执行。
线程方式还可用于数据的批处理以及网络系统中的信息发送与接收和其他相关处理等。
例如,图中给出了一个用户主机通过网络,向2台远程服务器进行远程调用(RPC)以获得相应结果的执行情况。
单线程时的RPC请求处理
多线程时的RPC请求处理
线程的分类
用户级线程
系统级线程(核心级线程)。
用户级线程(user level threads)
管理过程全部由用户程序完成,操作系统内核只对进程进行管理。
用户级线程创建与进程创建过程的不同之处:
- 用户级线程的调度算法和调度过程,全部由用户自行选择和确定。
- 用户级线程的调度算法只进行线程上下文切换,而不进行处理机切换,且其线程上下文切换是在内核不参与的情况下进行的。
- 进程的状态和所属线程状态可能不同步。
用户空间内实现进程
把线程库整个地放在用户空间,核心对线程一无所知。
在用户空间实现线程
核心级线程
操作系统内核进行管理
操作系统内核给应用程序提供相应的系统调用,和应用程序接口API,以使用户程序可以创建、执行、撤消线程。
核心级线程既可以被调度到一个处理机上并发执行,也可以被调度到不同的处理机上并行执行。
在核心空间实现线程
核心知道线程存在,并对它们实施管理
- 在多处理器系统中,核心可以同时调度同一进程的多个线程;
- 如果一个进程的某个线程阻塞了,核心可以调度同一个进程的另一个线程。
优点,核心线程本身也可以是多线程的。
缺点,主要是控制转移开销大。
操作系统内核既负责进程的调度,也负责进程内不同线程的调度工作。
因此,核心级线程不会出现进程处于阻塞或等待状态,而线程处于执行状态的情况
。
核心级线程技术也可用于内核程序自身,从而提高操作系统内核程序的执行效率。
与用户级线程相比,核心级线程的上下文切换时间要大于用户级线程的上下文切换时间。
图中给出了用户级线程、系统级线程,以及进程进行上下文切换时的各自的时间开销。
组合方式
多对一模型
(在核心级线程上由多个用户级线程,上图)
一对一模型
多对多模型
线程的执行特性
线程的状态和同步反映线程的执行特性。
线程有3个基本状态,即执行、就绪和阻塞。但是线程没有进程中的挂起状态。
也就是说,线程是一个只与内存和寄存器相关的概念,它的内容不会因交换而进入外存。
针对线程的3种基本状态,存在5种基本操作来转换线程的状态。
(1) 派生(spawn)
(2) 阻塞(Block)
(3) 激活(unblock)
(4) 调度(schedule)
(5) 结束(Finish)
线程的状态和操作关系如图所示。
(线程的状态与操作)
在某些情况下,某个线程被阻塞也可能导致该线程所属的进程被阻塞。
- 线程的另一个执行特性是同步。
- 由于同一进程中的所有线程共享该进程的所有资源和地址空间,任何线程对资源的操作都会对其他相关线程带来影响。
- 系统必须为线程的的执行提供同步控制机制,以防止因线程的执行而破坏其他的数据结构和给其他线程带来不利的影响。
- 线程中所使用的同步控制机制与进程中所使用的同步控制机制相同。