zoukankan      html  css  js  c++  java
  • 操作系统-进程(7)死锁和银行家算法

    允许多个进程并发执行共享系统资源时,系统必须提供同步机制和进程通信机制。然而,对这种机制使用不当的话,可能会出现进程永远被阻塞的现象。例如,两个进程分别等待对方占有的一个资源,于是两者都不能执行而处于永远等待,这种现象称为死锁。
     
    死锁产生的四个必要条件:
    1. 互斥条件: 进程应互斥使用资源,任一时刻一个资源仅为一个进程独占 
    2. 占有和等待条件: 一个进程请求资源得不到满足而等待时,不释放已占有的资源
    3. 不剥夺条件: 任一进程不能从另一进程那里抢夺资源
    4. 循环等待条件: 存在一个循环等待链,每一个进程分别等待它前一个进程所持有的资源
    破坏第一个条件,把独占型资源改造成共享性资源,使资源可同时访问而不是互斥使用。这是一个简单的办法,但对许多资源往往是不能做到的
    采用静态分配可以破坏第二个条件。所谓静态分配是指一个进程必须在执行前就申请它所要的全部资源,并且直到它所要的资源都得到满足之后才开始执行,所有并发执行的进程要求的资源总和不超过系统拥有的资源数。采用静态分配后,进程在执行中不再申请资源,因而不会出现占有了某些资源再等待另一些资源的情况。但这么做资源使用率不高。
    采用剥夺式调度方法可以破坏第三个条件,但剥夺式调度方法目前只适用于对主存资源和处理器资源的分配,而不适用于所有资源。
    层次分配策略将阻止第四个条件的出现,资源被分成多个层次,一个进程得到某一层的一个资源后,它只能再申请更高层的资源;当一个进程要释放某层的一个资源时,必须先释放所占用的更高层的资源; 当一个进程获得了某一层的一个资源后,它想再申请该层中的另一个资源,那么,必须先释放该层中的已占资源。
     
    当不能防止死锁的产生时,如果能掌握并发进程中与每个进程有关的资源申请情况,仍然可以避免死锁的发生。只需在为申请者分配资源前先测试系统状态,若把资源分配给申请者会产生死锁的话,则拒绝分配,否则接收申请,为它分配资源。
    银行家算法(资源分配拒绝法):每个进程pk必须预先说明所要的最大资源量Clain[k , *],每次提出部分资源的申请Request[k , *]并获得分配;如果操作系统所拥有的最大资源量满足进程对资源的最大需求量Need[k , *],那么操作系统一定会接纳进程并满足其资源需求,进程在运行后应在有限时间内将资源全部归还操作系统;操作系统在收到一个进程的资源申请时,可能会因资源不足而让进程等待,但保证在有限时间内让进程获得资源。
    算法考虑的最坏的情况:所有进程同时要使用它们所声明的资源最大需求数。此时操作系统中所有进程加上新启动进程对资源Ri的需求量,不能超过系统拥有的最大资源数。
    即系统若要启动一个新进程工作,其对资源Ri的需求必须满足Ri ≥ Clain[1 , i] + …+ Clain[n , i] + Clain[n+1 , i]
    系统安全性:存在一个进程序列,对进程pk满足Need[k , i] ≤ Available[i] + Allocation[1 , i] + … + Allocation[n , i]
    银行家算法分配步骤:
    (1)若Request[i , *] ≤ Need[i , *],则进程的资源申请量超过了自身的最大需求量,出错处理
    (2)若Request[i , *] ≤ Available[i , *],则进程的资源申请量超过了操作系统当前拥有的最大资源量,让其等待
    (3)系统对进程pi请求的资源进行试探性分配
                Allocation[i , *] = Allocation[i , *] + Request[i , *]
                Available[*] = Available[*] - Request[i , *]
                Need[i , *] = Need[i , *] - Request[i , *]
    (4)转向安全测试算法,如果返回安全状态则承认试分配,否则抛弃试分配,进程等待,还原试分配的操作
    (5)执行初始化操作,定义工作向量集合Work[i] = Available[*]。从进程集合中找到满足need[k , *] ≤ Work[*]的进程pk,找到后释放其占有的资源,Work[*] = Work[*] + Allocation[k , *],把pk从进程集合中去掉,再继续找下一个进程,直到找到安全的、绝对不会产生死锁的进程运行序列。
     
    解决死锁问题的另一条途径是死锁检测方法,这种方法对资源的分配不加限制,但系统定时运行一个死锁检测程序,判断系统内是否已出现死锁,若检测到死锁则设法加以解除。
    检测的一种方法:可设置两张表格来记录进程使用资源的情况
    等待资源表记录每个被阻塞进程等待的资源,占用资源表记录每个进程占有的资源
    进程申请资源时,先查该资源是否为其它进程所占用;若资源空闲,则把该资源分配给申请者且登入占用资源表;否则,则登入等待资源表
    死锁检测程序定时检测这两张表,若有进程Pi等待资源R,且资源R被进程Pj占用,则说Pi和Pj具有“等待占用关系”,记为W(Pi, Pj)
    死锁检测程序反复检测这两张表,可以列出所有的“等待占用关系”
    如果出现W(Pi, Pj)、W(Pj, Pt)、……、W(Pm, Pn)、W(Pn, Pi)时,系统中存在一组循环等待资源的进程,也就是说出现了死锁
    把两张表格中记录的进程使用和等待资源的情况用一个矩阵A来表示
    死锁检测程序可用Warshall的传递闭包算法检测是否有死锁发生,算法详见离散数学:https://www.cnblogs.com/yangyuliufeng/p/10680560.html
     
    检测出死锁后,解除系统死锁的方法主要有:
    (1)结束所有进程的执行并重新启动操作系统
    (2)撤销陷入死锁的所有进程,解除死锁,继续运行
    (3)逐个撤销陷入死锁的进程,回收其资源并重新分派,直至死锁解除。先撤销的进程可以选择CPU消耗时间最少者、产生的输出量最少者、预计剩余执行时间最长者、分得的资源数量最少者、优先级最低者
    (4)剥夺陷入死锁的进程所占用的资源,但不撤销进程,直到死锁解除
    (5)根据系统保存的检查点让所有进程回退,直到足以解除死锁(要求系统建立保存检查点、回退、重启机制)
  • 相关阅读:
    网络基础
    socket编程初识
    socket之黏包
    socketserver和socket的补充(验证客户端合法性)
    操作系统介绍
    进程初识和multiprocessing模块之Process
    进程Process之join、daemon(守护)、terminate(关闭)
    进程间通信(队列、管道)、消费者模型和进程池(apply,apply_async,map)
    数字证书私钥sign及验证
    JAVA获取密钥公钥的keytool的使用
  • 原文地址:https://www.cnblogs.com/yangyuliufeng/p/9626540.html
Copyright © 2011-2022 走看看