为什么不安全状态不总是导致死锁?


10

我正在阅读Galvin的《操作系统》,发现以下内容,

但是,并非所有不安全状态都是死锁。不安全的状态可能导致死锁

有人可以解释一下死锁!=不安全状态吗?我在这里也抓住了同一条线

如果不存在安全序列,则系统处于不安全状态,这可能导致死锁。(所有安全状态均无死锁,但并非所有不安全状态都会导致死锁。)


1
死锁可以与间歇性发生的竞争状况类似。仅当特定序列排队时,不安全代码才会触发死锁。该序列可能“随时发生”又称为“等待发生的事故” ...
vzn 2015年

不安全状态意味着从理论上讲可能存在死锁。当某些特定的事情发生时,可能会发生死锁。对于安全状态,无论发生什么事情,都不会出现死锁。
nishantbhardwaj2002 '16

1
出于完全相同的原因,任何危险情况(在现实生活中)并不总是导致实际发生坏事。
David Richerby

Answers:


14

死锁意味着特定的东西:当前有两个(或更多)被阻塞的进程正在等待对方。

不安全的状态下,您还可能处于将来某个时候可能会出现死锁的情况,但是尚未发生,因为其中一个或两个过程实际上尚未开始等待。

考虑以下示例:

Process A                  Process B
lock X                     lock Y           # state is "unsafe"
                           unlock Y
lock Y                                      # state is back to "safe" (no deadlock this time.  We got lucky.)

您提供的链接的第7.5.1节中有一个更有趣的示例:

考虑具有12个磁带机的系统,其中:

Process       Max Need       Current
P0:             10              5
P2:              9              3

这是不安全的状态。但是我们并没有陷入僵局。仅有4个可用驱动器,因此,例如,如果P0 确实请求额外的5个驱动器,而P2 确实请求另外的1个驱动器,我们将陷入僵局,但尚未发生。P0可能不再请求更多驱动器,而是可能释放它已经拥有的驱动器。该Max need程序涵盖了程序的所有可能执行,而这可能不是我们需要P0中所有10个驱动器的执行之一。


非常感谢您,先生!我讨厌我的课本不清楚...
Ning

但是我也有一些问题:(1)您说[[] Max需要超过了程序的所有可能执行[。“],但是您还说了[”]如果P0确实请求了另外5个,而P2确实请求了另外一个1,我们死锁[。“],其中(1)表示如果未达到“最大需求”,则可能会出现死锁,而(2)意味着必须在未实现时出现死锁?

我的推理正确吗?:如果P2 确实要求额外的1 并且完成,则空闲磁带变为(4 + 3 = 7),并且由于P1请求额外的5,所以可以实现,因此没有死锁。但是,如果P2 没有完成,则死锁会发生,因为即使P1仅需要5个完成,仍然4 <5。

对于最后一个示例:P0请求附加5,然后5 + 5 + 3 = 13> 12,因此P0必须等待P2生成死锁,只需让P2请求附加1。
Bit_hcAlgorithm

7

只是为了阐明“漫游逻辑”在说什么。

假设我有两个线程都需要访问X和Y,并且没有同步,也没有修复死锁的机制。这是不安全的,因为一个人可以锁定X而另一个Y却不能继续进行。但这并不能保证。

Thread 1                    Thread 2
Lock X                      
Lock Y
OS Interrupts Thread 1 and passes control to Thread 2
                            Unable to lock needed resources.
OS Interrupts Thread 2 and passes control to Thread 1
Unlock X                    
Unlock Y                    
                            Lock Y
                            Lock X
 ....

这种情况并没有陷入僵局,但是可能会发生。由于线程的工作方式,没有固定的流程。操作系统控制线程,因此可能会发生以下情况:

Thread 1                    Thread 2
Lock X        
OS Interrupts Thread 1 and passes control to Thread 2
                            Lock Y              
DEADLOCK Thread 1 needs Y, Thread 2 needs X. Neither knows to back down and simply waits.

1

安全状态肯定是没有死锁的,但是如果您不能满足所有防止死锁的要求,则可能会发生。例如,如果两个线程分别在启动线程A和启动线程B时陷入死锁,但是在启动相反的线程(B,A)时它们将正常工作-让我假设B更好;)系统状态不安全,但幸运的是,启动顺序将起作用。没有死锁,但是有可能。如果您还手动同步它们-顺序良好-危险-由于某些原因它们可能不会按您希望的方式被触发-系统仍然不安全(由于可能出现死锁),但是可能性很小。如果发生某些外部事件,例如继续执行后冻结线程或中断,它将失败。

您必须认识到-安全状态足以避免死锁,但不安全只是必要条件。现在很难立即编写代码,但是我可以搜索一些。我确实在Ada中遇到了超过99/100次的代码,它可以正常运行几周(然后由于服务器重新启动而不是死锁而停止了),但是偶尔它在进入死锁状态几秒钟后便崩溃了。

让我通过比较除法来添加一些简单的示例:如果您的函数除以c / d并返回结果,而不检查d是否等于0,则可能存在除以零的错误,因此代码是不安全的(意图相同),但是直到您进行这种划分,一切都很好,但是经过理论分析,代码是不安全的,并且可能会陷入无法正确处理的未定义行为。


0

这是我对此的理解(如果我错了,请纠正我):(A)如果出现死锁,则意味着存在一个周期(必要条件之一)(B)周期是死锁的强制条件(对于单锁和多锁)实例资源)

因此,我们现在可以证明存在一个可能不会导致死锁带周期的不安全状态 的循环,您可以在此处看到一个存在的循环,这意味着找到了不安全状态,但是由于参与该循环的资源R2可能会破坏该状态,因此这可能不会导致死锁。进程P3完成并释放它后立即循环(请记住P3没有任何依赖关系或在等待任何其他资源)。


2
欢迎光临本站!要点:最好避免用书面英语表达“可能不会”一词,因为目前尚不清楚它的意思是“一定不要”(“您不得在这里停车”)还是“可能不要”(“您可能不喜欢这部电影” ”。)
David Richerby

0

一个不安全的琐碎状态:线程1拥有锁A,然后拥有锁B,然后都将其解锁。线程2取得锁定B,然后锁定A,然后同时解锁。

这只会导致死锁如果线程2需要锁定装置B 只是线程1回吐锁定A之间,并试图采取锁B,或线程1需要锁定装置A 只是线程2回吐锁定装置B之间,试图把锁A.

如果线程1和线程2每小时随机执行一次,那么会有微秒的时间间隔,这实际上会导致死锁。这可能会在客户手中运行很长时间,直到最终您偶然遇到僵局。

闭着眼睛走过一条街。不安全 但是你并不总是被杀。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.