死锁

可以用一个经典的问题来引入死锁的概念:哲学家进餐问题


【OS】死锁以及预防方法_死锁

对于这五位哲学家来说,如果他们同时拿起左手边的筷子,那么所有哲学家就会想要拿起右手边的筷子,但是此时每位哲学家右手边都没有筷子了,此时每个哲学家就会陷入等待的状态,持有左手的筷子的同时,不停地等待右手边的筷子。这种状态如果没有外力来停止,就会一直持续下去。这种现象就是死锁。

因此死锁就是:在并发环境下,各进程因为竞争资源而造成的一种互相等待对方手里的资源,导致各进程都阻塞,无法向前推进的现象

死锁的必要条件

互斥条件

只有对必须互斥使用的资源的竞争才会导致死锁。比如哲学家进餐问题中的筷子,同一时间只允许被一个哲学家使用

不剥夺条件

进程所获得的资源在未使用完之前,不能被其他进程抢占,只能由该进程主动释放资源。比如哲学家进餐问题中,一个哲学家在需要右手边的筷子时,如果右手边筷子被占用,要进行等待,而不能直接抢夺右手边的筷子

请求和保持条件

进程已经保持了至少一个资源,但又提出了新的资源请求,而该资源又被其他进程占有,此时请求进程被阻塞,但又对自己已有的资源保持不放

循环等待条件

存在一个进程资源的循环等待链,链中的每一个进程已获得的资源同时被下一个进程所请求

预防死锁

因为必须具备四个必要条件,才能形成死锁,因此可以通过破坏这四个互斥条件来预防死锁的发生

破坏互斥条件

这个条件不建议达成。因为互斥条件是非共享资源所必需的,不仅不能改变,还应该加以保证

破坏请求和保持条件
  • 进程在开始运行之前,一次性将整个运行过程中所需要的全部资源都申请到位。比如在哲学家进餐问题中,一位哲学家要么拿到两双筷子开始进餐,要么就不进餐,这样就不会发生死锁现象。
    • 这种做法会导致资源利用率降低,使进程发生饥饿现象
  • 可以对上述做法进行改进。让进程只获得运行初期需要的资源,在运行过程中逐步释放已经分配好的使用完毕的资源,然后再请求新的资源。
破坏不剥夺条件

当一个已经持有了一些资源的进程在提出新的资源请求没有得到满足时,它必须释放已经保持的所有资源,待以后需要使用的时候再重新申请。这就意味着进程已占有的资源会被短暂地释放或者说是被抢占了。

破坏循环等待条件

可以采取顺序资源分配法,首先给系统中的资源编号,规定每个进程必须按照编号递增的顺序请求资源,同类资源一次性申请完成。

比如,这样一个死锁情况:

进程A拥有1号资源,请求2号资源,进程B拥有2号资源,请求3号资源,进程C拥有3号资源,请求1号资源

【OS】死锁以及预防方法_死锁_02

如果采取顺序资源分配法,那么进程C就不可能跳过申请1号资源,而去请求3号资源

也就是:

【OS】死锁以及预防方法_死锁_03

此时,循环等待链就不存在了