死锁的原理及避免死锁的方法

死锁

所谓死锁,指的是两个或两个以上的进程在执行过程中,由于竞争资源或者由于彼此通信而造成的一种阻塞的现象,如果无外力作用,那么它们都将无法推进下去。此时,称系统处于死锁状态或系统产生了死锁,这些永远在互相等待的进程称为死锁进程。

举例说明死锁:如果一个线程需要并行处理多个任务,那么就可以创建多个线程,但是线程多了,往往会产生冲突,当一个线程锁定了一个资源A,而又想去锁定资源B,而在另一个线程中,锁定了资源B,而又想去锁定资源A以完成自身的操作,两个线程都想得到对方的资源,而不愿意释放自己的资源,造成两个线程都在等待,而无法执行,此时就是死锁。

死锁的规范定义:集合中的每一个进程都在等待只能由本集合中的其他进程才能引发的事件,那么该组进程是死锁的。

注意 死锁与正常阻塞不一样
正常阻塞:事务请求被其他事务锁定的资源的锁时,发出请求的事务一直等到该锁被释放。默认情况下,除非设置了LOCK_TIMEOUT,否则SQL Server事务不会超时。因为发出请求的事务未执行任何操作来阻塞拥有锁的事务,所以该事务是被阻塞,而不是陷入了死锁。最后,拥有锁的事务将完成并释放锁,然后发出请求地事务将获取锁并继续执行。

产生条件

-互斥(资源独占): 一个资源每次只能被一个进程使用;
- 请求与保持(部分分配,占有申请):一个进程在申请新的资源的同时保持对原有资源的占有(只有这样才是动态申请,动态分配);
- 不可剥夺(不可强占):资源申请者不能强行地从资源占有者手中夺取资源,资源只能由占有者自愿释放;
- 循环等待:若干进程之间形成一种头尾相连的循环等待资源关。

循环等待的例子:例如,存在一个进程等待队列{P1, P2, ……, Pn},其中P1等待P2占有的资源,P2等待P3占有的资源,……, Pn等待P1占有的资源,形成一个进程等待环路。

以上四个条件是死锁产生的必要条件,只要系统发生死锁,这些条件必然成立,而只要上述条件之一不满足,就不会发生死锁。

产生原因

系统中的资源可以分为两类:可剥夺资源和不可剥夺资源。
可剥夺资源:是指某进程在获得这类资源后,该资源可以再被其他进程或系统剥夺。例如,优先权高的进程可以剥夺优先权低的进程的处理机;可把一个进程从一个存储区移到另一个存储区;在内存紧张时,甚至可将一个进程从内存调到外存上,即剥夺该进程在内存的空间。可见,CPU和主存均属于可剥夺性资源。对于这类资源是不会引起死锁的。
不可剥夺资源:当系统把某资源分配给某进程后,就不能将它强行收回,只能在进程用完后自行释放。例如,当一个进程已开始刻录光盘时,如果突然将刻录机分配给另一个进程,其结果必然会损坏正在刻录的光盘,因此只能等刻好光盘后由进程自己释放刻录机。另外磁带机、打印机也是不可剥夺资源。


  • 系统资源不足时,竞争不可剥夺资源引起进程死锁

在系统中所配置的不可剥夺资源,由于它们的数量不能满足诸进程运行的需要,会使进程在运行过程中,因争夺这些资源而陷于僵局。
例如,当系统中供多个进程共享的资源如打印机、公用队列等,其数目不足以满足诸进程的需要时,会引起诸进程对资源的竞争而产生死锁。
例如,系统中只有一台打印机R1和一台磁带机R2,可供进程P1和P2共享。假定PI已占用了打印机R1,P2已占用了磁带机R2,若P2继续要求打印机R1,P2将阻塞;P1若又要求磁带机,P1也将阻塞。于是,在P1和P2之间就形成了僵局,两个进程都在等待对方释放自己所需要的资源,但是它们又都因不能继续获得自己所需要的资源而不能继续推进,从而也不能释放自己所占有的资源,以致进入死锁状态。

  • 竞争临时资源引起死锁

    永久资源:上面所说的打印机资源属于可顺序重复使用型资源,称为永久资源。
    临时资源:还有一种所谓的临时资源,这是指由一个进程产生,被另一个进程使用,短时间后便无用的资源,故也称为消耗性资源,如硬件中断、信号、消息、缓冲区内的消息等,它也可能引起死锁。
    如果消息通信按如下顺序进行:
    P1: ···Relese(S1);Request(S3); ···
    P2: ···Relese(S2);Request(S1); ···
    P3: ···Relese(S3);Request(S2); ···
    并不可能发生死锁。
    但若改成下述的运行顺序:
    P1: ···Request(S3);Relese(S1);···
    P2: ···Request(S1);Relese(S2); ···
    P3: ···Request(S2);Relese(S3); ···
    则可能发生死锁。

  • 进程推进顺序不当引起死锁

    由于进程在运行中具有异步性特征,这可能使P1和P2两个进程按下述两种顺序向前推进。
    1) 进程推进顺序合法
    当进程P1和P2并发执行时,如果按照下述顺序推进:
    P1:Request(R1); P1:Request(R2); P1: Relese(R1);
    P1:Relese(R2); P2:Request(R2); P2:Request(R1);
    P2:Relese(R2);P2:Relese(R1);
    这两个进程便可顺利完成,这种不会引起进程死锁的推进顺序是合法的。
    2) 进程推进顺序非法
    若P1保持了资源R1,P2保持了资源R2,系统处于不安全状态,因为这两个进程再向前推进,便可能发生死锁。
    例如,当P1运行到P1:Request(R2)时,将因R2已被P2占用而阻塞;当P2运行到P2:Request(R1)时,也将因R1已被P1占用而阻塞,于是发生进程死锁。

  • 预防死锁

    预防死锁的方法是通过设置某些限制条件,去破坏产生死锁的四个必要条件中的一个或者几个,以避免发生死锁。
    由于互斥条件是非共享设备所必须的,不仅不能改变,还应该加以保证,因此,主要是破坏产生死锁的后三个条件。

    • 破坏请求与保持条件:对一个进程在请求资源时,它不能持有不可剥夺资源。
    • 破坏不可剥夺条件:对一个已经保持了某些不可剥夺资源的进程,提出新的资源请求而不能得到满足时,它必须释放已经保持的所有资源,待以后需要时再重新申请。
    • 破坏循环等待条件:对系统所有资源类型进行线性排列,并赋予不同序号。规定每个进程必须按序号递增的顺序请求资源。

    避免死锁的方法

    • 一次封锁法:每个进程(事务)将所有要使用的数据全部加锁,否则,就不能继续执行;
    • 顺序封锁法:预先对数据对象规定一个封锁顺序,所有进程(事务)都按这个顺序加锁;
    • 银行家算法:保证进程处于安全进程序列。

    有助于最大限度地降低死锁的方法

    • 按同一顺序访问对象;
    • 避免事务中的用户交互;
    • 保持事务简短并在一个批处理中;
    • 使用低隔离级别。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值