本文概述
如果我们用桌子的四腿站立模拟死锁, 那么我们也可以用四种情况模拟四腿, 这四种情况同时发生时会导致死锁。
但是, 如果我们折断桌脚之一, 桌肯定会掉落。死锁也会发生同样的情况, 如果我们能够违反四个必要条件之一并且不让它们同时出现, 那么我们可以防止死锁。
让我们看看如何预防每种情况。
1.互斥
从资源的角度来看, 相互切入的事实是, 一个资源永远不能被多个进程同时使用, 这很公平, 但这是造成僵局的主要原因。如果一个资源可能同时被多个进程使用, 则该进程将永远不会等待任何资源。
但是, 如果我们能够违反以互斥方式运行的资源, 则可以避免死锁。
假脱机
对于像打印机这样的设备, 可以进行假脱机。与打印机关联的内存可将每个进程的作业存储到其中。之后, 打印机收集所有作业, 并根据FCFS打印其中的每一项。通过使用这种机制, 该线程不必等待打印机, 它可以继续进行任何操作。稍后, 它将在产生时收集输出。
尽管假脱机处理可能是一种有效的方法, 可以避免相互排斥, 但是它存在两种问题。
- 这不能应用于所有资源。
- 在某个时间点之后, 可能会在进程之间产生争用条件, 以在该线轴中获得空间。
我们不能强行将资源同时用于多个进程, 因为这将不够公平, 并且性能可能会出现一些严重问题。因此, 在实践中我们不能违反互斥。
2.保持并等待
当进程持有资源并等待其他资源完成其任务时, 则保持等待状态。之所以会发生死锁, 是因为可能有一个以上的进程按循环顺序持有一个资源并等待其他资源。
但是, 我们必须找出某种机制, 使进程不占用任何资源或不等待。这意味着必须在执行开始之前为进程分配所有必需的资源。一旦开始执行, 进程就不能等待任何资源。
!(保持和等待)=!hold或!wait(保持和等待的否定是你不保持还是不等待)
如果进程最初声明了所有资源, 则可以实际实现这一点。但是, 这听起来很实用, 但是在计算机系统中无法完成, 因为一个线程最初无法确定必要的资源。
进程是由CPU执行的指令集。每个指令可能多次需要多个资源。操作系统无法解决这一需求。
该方法的问题是:
- 几乎不可能。
- 由于某些进程可能会长时间占用资源, 因此饥饿的可能性会增加。
3.无抢占
死锁的产生是由于进程一旦启动就无法停止。但是, 如果我们将资源从导致死锁的进程中移走, 则可以防止死锁。
这根本不是一个好方法, 因为如果我们占用了该线程正在使用的资源, 那么该资源到现在为止所做的所有工作都会变得不一致。
考虑任何进程正在使用打印机。如果我们将打印机从该线程中移开, 然后将其分配给其他线程, 则所有已打印的数据可能会变得不一致且无效, 并且该线程无法从离开的地方重新开始打印, 从而导致性能下降效率低下。
4.循环等待
为了避免循环等待, 我们可以为每个资源分配一个优先级编号。进程无法请求优先级较低的资源。这样可以确保没有一个进程可以请求其他进程正在使用的资源, 并且不会形成任何循环。
在所有方法中, 违反循环等待是唯一可以实际实施的方法。
评论前必须登录!
注册