目录
线程、程序、进程
进程是程序的一次执行过程,是系统运行程序的基本单位,因此进程是动态的。系统运行一个程序即是一个进程从创建,运行到消亡的过程。
程序是含有指令和数据的文件,被存储在磁盘或其他的数据存储设备中,也就是说程序是静态的代码。
线程:
-
线程是进程划分成的更小的运行单位,也叫轻量级进程,一个进程在执行过程中可以产生多个线程。
-
线程和进程最大的不同是各进程是独立的,而各线程则不一定,因为同一进程中的线程极有可能相互影响。
-
线程执行开销小,但不利于资源的管理和保护;而进程正相反。
死锁的必要条件?
-
互斥条件:一个资源每次只能被一个线程使用
-
请求与保持条件:一个线程因请求资源而阻塞时,对已获得的资源保持不放
-
不剥夺条件:进程已经获得的资源,在未使用完之前,不能强行剥夺
-
循环等待条件:若干线程之间形成一种头尾相接的循环等待资源关系
如何避免死锁?
一般的情况下,有预防,避免,检测和解除四种。
-
预防 是采用某种策略,限制并发进程对资源的请求,从而使得死锁的必要条件在系统执行的任何时间上都不满足。
-
避免则是系统在分配资源时,根据资源的使用情况提前做出预测,从而避免死锁的发生
-
检测是指系统设有专门的机构,当死锁发生时,该机构能够检测死锁的发生,并精确地确定与死锁有关的进程和资源。
-
解除 是与检测相配套的一种措施,用于将进程从死锁状态下解脱出来。
死锁的预防
也就是破坏死锁产生的必要条件
破坏互斥条件:使得资源是可以同时访问的,这是种简单的方法,磁盘就可以用这种方法管理,但是,有很多资源 往往是不能同时访问的 ,所以这种做法在大多数的场合是行不通的。
破坏不剥夺:采用 剥夺式调度算法,但剥夺式调度方法目前一般仅适用于 主存资源 和 处理器资源 的分配,并不适用于所有的资源,会导致资源利用率下降。
所以一般是通过破坏请求保持和循环等待。
1、静态分配策略
静态分配策略可以破坏请求保持条件。所谓静态分配策略,就是指一个进程必须在执行前就申请到它所需要的全部资源,并且知道它所要的资源都得到满足之后才开始执行。进程要么占有所有的资源然后开始执行,要么不占有资源,不会出现占有一些资源等待一些资源的情况。
静态分配策略逻辑简单,实现也很容易,但这种策略 严重地降低了资源利用率,因为在每个进程所占有的资源中,有些资源是在比较靠后的执行时间里采用的,甚至有些资源是在额外的情况下才使用的,这样就可能造成一个进程占有了一些 几乎不用的资源而使其他需要该资源的进程产生等待 的情况。
2、层次分配策略
层次分配策略破坏了循环等待条件。它使得所有的资源被分成了多个层次,一个进程得到某一次的一个资源后,它只能再申请较高一层的资源;当一个进程要释放某层的一个资源时,必须先释放所占用的较高层的资源,按这种策略,是不可能出现循环等待链的,因为那样的话,就出现了已经申请了较高层的资源,反而去申请了较低层的资源,不符合层次分配策略。
死锁的避免(银行家)
将系统的状态分为 安全状态 和 不安全状态 ,每当在未申请者分配资源前先测试系统状态,若把系统资源分配给申请者会产生死锁,则拒绝分配,否则接受申请,并为它分配资源。
安全状态:如果操作系统能够保证所有的进程在有限的时间内得到需要的全部资源,则称系统处于安全状态。显然,系统处于安全状态则不会死锁,系统若处于不安全状态则可能死锁。
如何保证系统保持在安全状态?通过算法,其中最具代表性的 避免死锁算法 就是 Dijkstra 的银行家算法。
银行家算法:当一个进程申请使用资源的时候,银行家算法通过先 试探 分配给该进程资源,然后通过 安全性算法 判断分配后系统是否处于安全状态,若不安全则试探分配作废,让该进程继续等待,若能够进入到安全的状态,则就 真的分配资源给该进程。
死锁的检测
对资源的分配不加以任何限制,也不采取死锁避免措施,但系统 定时地运行一个 “死锁检测” 的程序,判断系统内是否出现死锁,如果检测到系统发生了死锁,再采取措施去解除它。
进程-资源分配图
操作系统中的每一刻时刻的系统状态都可以用进程-资源分配图来表示,进程-资源分配图是描述进程和资源申请及分配关系的一种有向图,可用于检测系统是否处于死锁状态。
死锁检测步骤
-
如果进程-资源分配图中无环路,则此时系统没有发生死锁
-
如果进程-资源分配图中有环路,且每个资源类仅有一个资源,则系统中已经发生了死锁。
-
如果进程-资源分配图中有环路,且涉及到的资源类有多个资源,此时系统未必会发生死锁。如果能在进程-资源分配图中找出一个 既不阻塞又非独立的进程 ,该进程能够在有限的时间内归还占有的资源,也就是把边给消除掉了,重复此过程,直到能在有限的时间内 消除所有的边 ,则不会发生死锁,否则会发生死锁。(消除边的过程类似于 拓扑排序)
死锁的解除
当死锁检测程序检测到存在死锁发生时,应设法让其解除,让系统从死锁状态中恢复过来,常用的解除死锁的方法有以下四种:
-
立即结束所有进程的执行,重新启动操作系统:这种方法简单,但以前所在的工作全部作废,损失很大。
-
撤销涉及死锁的所有进程,解除死锁后继续运行:这种方法能彻底打破死锁的循环等待条件,但将付出很大代价,例如有些进程可能已经计算了很长时间,由于被撤销而使产生的部分结果也被消除了,再重新执行时还要再次进行计算。
-
逐个撤销涉及死锁的进程,回收其资源直至死锁解除。
-
抢占资源:从涉及死锁的一个或几个进程中抢占资源,把夺得的资源再分配给涉及死锁的进程直至死锁解除。