写给大忙人看的死锁全详解 (2)

现在让我们考虑两个进程的情况,A 和 B ,还存在两个资源。如下所示

typedef int semaphore; semaphore aResource; semaphore bResource; void processA(void){ down(&aResource); down(&bResource); useBothResource(); up(&bResource); up(&aResource); } void processB(void){ down(&aResource); down(&bResource); useBothResource(); up(&bResource); up(&aResource); }

在上述代码中,两个进程以相同的顺序访问资源。在这段代码中,一个进程在另一个进程之前获取资源,如果另外一个进程想在第一个进程释放之前获取资源,那么它会由于资源的加锁而阻塞,直到该资源可用为止。

在下面这段代码中,有一些变化

typedef int semaphore; semaphore aResource; semaphore bResource; void processA(void){ down(&aResource); down(&bResource); useBothResource(); up(&bResource); up(&aResource); } void processB(void){ down(&bResource); // 变化的代码 down(&aResource); // 变化的代码 useBothResource(); up(&aResource); // 变化的代码 up(&bResource); // 变化的代码 }

这种情况就不同了,可能会发生同时获取两个资源并有效地阻塞另一个过程,直到完成为止。也就是说,可能会发生进程 A 获取资源 A 的同时进程 B 获取资源 B 的情况。然后每个进程在尝试获取另一个资源时被阻塞。

在这里我们会发现一个简单的获取资源顺序的问题就会造成死锁,所以死锁是很容易发生的,所以下面我们就对死锁做一个详细的认识和介绍。

死锁

如果要对死锁进行一个定义的话,下面的定义比较贴切

如果一组进程中的每个进程都在等待一个事件,而这个事件只能由该组中的另一个进程触发,这种情况会导致死锁

简单一点来表述一下,就是每个进程都在等待其他进程释放资源,而其他资源也在等待每个进程释放资源,这样没有进程抢先释放自己的资源,这种情况会产生死锁,所有进程都会无限的等待下去。

换句话说,死锁进程结合中的每个进程都在等待另一个死锁进程已经占有的资源。但是由于所有进程都不能运行,它们之中任何一个资源都无法释放资源,所以没有一个进程可以被唤醒。这种死锁也被称为资源死锁(resource deadlock)。资源死锁是最常见的类型,但不是所有的类型,我们后面会介绍其他类型,我们先来介绍资源死锁

资源死锁的条件

针对我们上面的描述,资源死锁可能出现的情况主要有

互斥条件:每个资源都被分配给了一个进程或者资源是可用的

保持和等待条件:已经获取资源的进程被认为能够获取新的资源

不可抢占条件:分配给一个进程的资源不能强制的从其他进程抢占资源,它只能由占有它的进程显示释放

循环等待:死锁发生时,系统中一定有两个或者两个以上的进程组成一个循环,循环中的每个进程都在等待下一个进程释放的资源。

发生死锁时,上面的情况必须同时会发生。如果其中任意一个条件不会成立,死锁就不会发生。可以通过破坏其中任意一个条件来破坏死锁,下面这些破坏条件就是我们探讨的重点

死锁模型

Holt 在 1972 年提出对死锁进行建模,建模的标准如下:

圆形表示进程

方形表示资源

从资源节点到进程节点表示资源已经被进程占用,如下图所示

写给大忙人看的死锁全详解

在上图中表示当前资源 R 正在被 A 进程所占用

由进程节点到资源节点的有向图表示当前进程正在请求资源,并且该进程已经被阻塞,处于等待这个资源的状态

写给大忙人看的死锁全详解

在上图中,表示的含义是进程 B 正在请求资源 S 。Holt 认为,死锁的描述应该如下

写给大忙人看的死锁全详解

这是一个死锁的过程,进程 C 等待资源 T 的释放,资源 T 却已经被进程 D 占用,进程 D 等待请求占用资源 U ,资源 U 却已经被线程 C 占用,从而形成环。

总结一点:吃着碗里的看着锅里的容易死锁

那么如何避免死锁呢?我们还是通过死锁模型来聊一聊

假设有三个进程 (A、B、C) 和三个资源(R、S、T) 。三个进程对资源的请求和释放序列如下图所示

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zwjsww.html