死锁的基本介绍

一、死锁是什么?

死锁,是指多个线程同时被阻塞,其中一个或者全部线程都在等待某个资源,由于资源争夺而造成的一中僵局。若无外力推进,他们都将无法推进。由于无限期的阻塞,程序没有办法进行正常终止。

举个例子~
场景:两个人一起去吃饭,桌上有辣椒和醋,两人都需要加辣椒和醋

A拿起辣椒,B拿起醋

A说:你先把醋给我用,我用完了把辣椒给你

B说:你先把辣椒给我用,我用完了把醋给你

如果两个人互不相让,就会形成死锁。
这里的辣椒和醋就相当于是两把锁。

在死锁中,讨论最多的是哲学家问题

在这里插入图片描述

  • 有一个桌子,围着4个哲学家。桌子上放着一份菜, 每个哲学家两两之间, 放着一根筷子。
  • 每个哲学家只做两件事: 思考人生 或者 吃面条。 思考人生的时候就会放下筷子,吃面条就会拿起左右两边的筷子(先拿起左边, 再拿起右边)
  • 如果哲学家发现筷子拿不起来了(被占用了),就会阻塞等待。
  • 假设同一时刻, 哲学家同时拿起左手边的筷子, 然后再尝试拿右手的筷子, 就会发现右手的筷子都被占用了。由于哲学家们互不相让,这个时候就形成了死锁
    如下图的情况:每个人拿了左左手的筷子,右手的被占用了
    在这里插入图片描述
    解决办法: 给每个筷子编号,约定让哲学家先拿编号小的,再拿编号大的。而不是,按照左右手来拿。这样,就可以避免死锁。
    在这里插入图片描述

二、死锁产生的原因

1. 死锁产生的必要条件

  • 互斥使用,即当资源被一个线程使用(占有)时,别的线程不能使用。
  • 不可剥夺,资源请求者不能强制从资源占有者手中夺取资源,资源只能由资源占有者主动释放。
  • 请求和保持,即当资源请求者在请求其他的资源的同时保持对原有资源的占有。
  • 循环等待,即存在一个等待队列:P1占有P2的资源,P2占有P3的资源,P3占有P1的资源。这样就形成了环路等待。

当上述四个条件都成立的时候,就会形成死锁。只要打破上述的条件之一,就会

2. 产生原因

(1)资源竞争

当多个进程共享资源,如果资源数目小于进程数,形成资源竞争,造成死锁

(2)可剥夺资源和不可剥夺资源

  • 可剥夺资源:当一个进程获得资源后,该资源可被其他进程或者系统剥夺。比如,优先级高的进程剥夺优先级低的进程的资源。
  • 不可剥夺资源:当系统把这类资源分配给某进程后,再不能强行收回,只能在进程用完后自行释放,如磁带机、打印机等。

(3)竞争不可剥夺资源

如果系统分配的不可剥夺资源数目小于进程所需,就会造成资源竞争,形成僵局。

举个例子~

系统中有打印机A,磁带机B,进程P1和P2共享。

假如,进程P1获得打印机A,进程P2获得磁带机B。

若P1继续要求磁带机B,由于P2占用,所以阻塞。P2又要求打印机A,但是被P1占用,所以P2阻塞。

P1和P2之间就形成了僵局,两个进程都在等待对方释放自己所需要的资源。

一旦获得资源,不能强制收回,只能等待进程自己释放。
所以,它们又都因不能继续获得自己所需要的资源而不能继续推进,从而也不能释放自己所占有的资源,以致进入死锁状态。

(3)竞争临时资源

临时资源指的就是进程短暂的用过,之后就不再使用了。比如硬件中断、信号、消息、缓冲区内的消息等,它也可能引起死锁。

以下情况也会造成死锁:

  • 进程推进顺序不合法
    比如,进程P1 P2此时各自获得资源A B,但是,P1需要得到B后再释放资源,P2需要得到A后再释放资源,此时系统不安全。如果再进行推进,就会死锁

三、如何避免和解决死锁?

1. 预防死锁

通过设置限制条件,破坏死锁的必要条件

  • 一次性分配所有资源,这样就不会再请求资源了
  • 只要有一个资源得不到分配,也不给该进程分配其他资源
  • 当某进程获得了部分资源,但得不到其它资源,则释放已占有的资源
  • 系统给每类资源赋予一个编号,每一个进程按编号递增的顺序请求资源,释放则相反

2. 避免死锁

在资源分配时,使用某种方法避免系统进入不安全的状态。

银行家算法

首先解释一下安全状态不安全状态

安全状态:如果存在一个由系统中所有进程构成的安全序列P1,…,Pn,则系统处于安全状态。安全状态一定是没有死锁发生。

不安全状态:不存在一个安全序列,不安全状态不一定导致死锁。

数据结构

  • 可利用资源向量Available

    是一个含有m个元素的数组,其中的每一个元素代表一类可利用的资源数目。如果Available[j]=K,则表示系统中现有Rj类资源K个。

  • 最大需求矩阵Max

    这是一个n×m的矩阵,定义了系统中n个进程中的每一个进程对m类资源的最大需求。如果Max[i,j]=K,则表示进程i需要Rj类资源的最大数目为K。

  • 分配矩阵Allocation

    这是一个n×m的矩阵,它定义了系统中每一类资源当前已分配给每一进程的资源数。如果Allocation[i,j]=K,则表示进程i当前已分得Rj类资源的 数目为K。

  • 需求矩阵Need

    这是一个n×m的矩阵,用以表示每一个进程尚需的各类资源数。如果Need[i,j]=K,则表示进程i还需要Rj类资源K个。

    Need[i,j]=Max[i,j]-Allocation[i,j]

算法描述

  • 假设Request是Pi的请求向量,Request[j] = k,代表Pi请求的Rj类资源是k个。
    执行如下步骤

  • 如果Request[j] <= Need[i,j],执行第二步。否则,出错。

  • 如果Request[j] <= Available[j],执行第三步。否则,出错,需要等待。

  • 系统试探分配资源,修改相关数据:

    Available[j] = Available[j] - Requesti[j];

    Allocation[i,j] = Allocation[i,j] + Requesti[j];

    Need[i,j] = Need[i,j] - Requesti[j];

  • 系统执行安全性检查,如安全,则分配成立;否则试探险性分配作废,系统恢复原状,进程等待。

安全性检查算法

  • 设置两个工作向量Work=AVAILABLE;FINISH

  • 从进程集合中找到一个满足下述条件的进程,

    FINISH==false;
    NEED<=Work;

    如满足,执行(3)
    否则,执行(4)

  • 设进程获得资源,可顺利执行,直至完成,从而释放资源。

    Work=Work+ALLOCATION;
    Finish=true;

    返回第二步

  • 如所有的进程Finish= true,则表示安全,否则系统不安全

3. 检测死锁

允许系统在运行过程中发生死锁。但是通过系统检测后,能及时地检测出死锁的发生,并精确地确定与死锁有关的进程和资源。

4. 解除死锁

发生死锁的时候,把进程从死锁的状态解脱出来

  • 27
    点赞
  • 82
    收藏
    觉得还不错? 一键收藏
  • 13
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 13
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值