死锁的概念 在多道程序系统中,由于多个进程的并发执行,改善了系统资源的利用率并提高了系统的处理能力。然而,多个进程的并发执行也带来了新的问题———死锁。 当多个进程因竞争系统资源或相互通信而处于永远阻塞状态时,若无外力作用,这些进程都将无法向前推进。这些进程中的每一个进程,均无限期地等待此组进程中某个其他进程占有的、自己永远无法得到的资源,这种现象称为死锁。 图1:死锁 [size=10.5000pt]1. 线程A或者B需要过独木桥(使用该进程),而C还没有走完(进程还在占用),于是三方僵死; [size=10.5000pt]2. 也可以是没有C 的情况下,A和B互不礼让僵死.A和B都认为自己优先级较高应该使用该进程. 死锁产生的原因 [size=10.5000pt]A. 系统资源不足 [size=10.5000pt]B. 进程推进顺序不当 系统资源不足是产生死锁的根本原因,设计操作系统的目的就是使并发进程共享系统资源。而进程推进顺序不当是产生死锁的重要原因,当系统资源刚好够进程使用时,进程的推进顺序不当就很容易导致进程彼此占有对方需要的资源,从而导致死锁。 死锁产生的必要条件 [size=10.5000pt]A. 互斥条件 [size=10.5000pt]B. 不剥夺条件 [size=10.5000pt]C. 请求与保持条件 [size=10.5000pt]D. 环路等待条件 处理死锁的基本方法 [size=10.5000pt]A. 鸵鸟算法 [size=10.5000pt]B. 预防死锁 [size=10.5000pt]C. 避免死锁 [size=10.5000pt]D. 检测及解除死锁 死锁的预防 想要防止死锁的发生,只需要破坏死锁产生的4个必要条件之一即可。 [size=10.5000pt]1. 通过破坏互斥条件来防止死锁的发生时不大可能的。 [size=10.5000pt]2. 不剥夺条件----破坏此条件的策略实现比较复杂。 [size=10.5000pt]3. 为了破坏请求和保持条件,可以采用预先静态分配方法。 [size=10.5000pt]4. 为了破坏环路等待条件,可以采用有序资源分配法。 死锁的避免 [size=10.5000pt]1. 安全状态与不安全状态 [size=10.5000pt]2. 银行家算法 死锁与饿死 死锁、饥饿、饿死通常是容易混淆的概念 当进程等待时间给进程推进和响应带来明显影响时,则称此时发生了进程饿死,当饥饿到一定程度,进程所赋予的任务即使完成也不再具有实际意义时,称该进程被饿死。 考虑一台打印机分配的例子,当有多个进程需要打印文件时,系统按照短作业优先(SJF)的策略排序,该策略具有平均等待时间短的优点,似乎非常合理,但当短文件打印任务源源不断出现时,长文件的打印任务将被无限延期推迟,导致饥饿以至饿死。 图2:饿死 这是个独木桥(单进程),桥上只能走一个人,B来到时A在桥上,B等待;而此时比B年龄小的C来了,B让C现行(A走完后系统把进程分给了C),C上桥后,D又来了,B又让D现行(C走完后系统把进程分个了D),以此类推B一直是等待状态. 与饥饿相关的另一个概念是活锁。在忙时等待条件下发生的饥饿,称为活锁,例如不公平的互斥算法。虽然此时进程仍然在执行,但有些进程由于无法调度执行,好像发生了死锁一样。 图3:活锁 饿死与死锁有一定联系:二者都是由于竞争资源而引起的,但又有明显的差别,主要表现在如下几个方面。 1. 从进程状态考虑,死锁进程都处于等待状态;忙时等待(处于运行或就绪状态)的进程并非处于等待状态,但却可能被饿死。 2. 死锁进程等待的是永远不会被释放的资源;而饿死进程等待的是会被释放但却不会分配给自己的资源,表现为等待时间没有上界(排队等待或忙时等待)。 3. 死锁一定发生了循环等待,而饿死则不然。这也表明通过资源分配图可以检测死锁存在与否,但却不能检测是否有进程饿死。 4. 死锁一定涉及多个进程,而饥饿或被饿死的进程可能只有一个。 饥饿与饿死与资源分配策略有关,因而可从公平性方面考虑防止饥饿与饿死,以确保所有进程不被忽视,如多级反馈队列调度算法。
阻塞
锁就是对象 锁的作用是保证线程同步,解决线程安全问题。 持有锁的线程可以在同步中执行,没有锁的线程即使获得cpu执行权,也进不去。
|