栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

死锁的定义 和 处理策略

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

死锁的定义 和 处理策略

目录

一、死锁的定义:

二、发生资源死锁的四个必要条件:

三、死锁的模型

四、四种处理死锁的策略:

五、经典的IPC问题     哲学家就餐问题


一、死锁的定义:

如果一个进程集合中的  每个进程  都在等待 只能由进程集合中的其他进程 才能引发的事件,那么,该进程集合就是死锁的。

进程的数量以及占有或者请求的资源数量和种类都是无关紧要的,而且无论资源是何种类型(软件或者硬件)都会发生这种结果。这种死锁称为 资源死锁(resource deadlock),这是常见的类型。

由于所有的进程都在等待,所有没有一个进程能引发可以唤醒该进程集合中的其他进程的事件, 这样, 所有的进程都 会无限期的等待下去。

二、发生资源死锁的四个必要条件:

1. 互斥条件

        每个资源要么已经分配给一个进程,要么就是可用的。

2. 占有和等待条件

        已经得到了某个资源的进程,可以再请求新的资源。

3. 不可抢占条件

        已经分配给一个进程的资源不能强制性地被抢占,它只能被占有它的进程显式地释放。

4. 环路等待条件

        死锁发生时,系统中一定有由两个或两个以上的进程组成的一条环路,该环路中的每个进程都在等待着下一个进程所占有的资源。

死锁发生时,以上四个条件一定是同时满足的。 如果其中任何一个条件不成立,死锁就不会发生。

三、死锁的模型

用圆形表示 进程, 用方形表示 资源。     从资源节点到进程节点的有向边,代表该资源已被请求、授权并被进程占用。   从进程节点到资源节点的有向边,代表当前进程正在请求该资源,并且该进程已被阻塞,处于等待该资源的状态。

                                                                                   

 左图含义是: 当前资源R正被进程A占用   ;  右图含义是: 进程B正在等待着资源S

 死锁的模型示例如下:

 上图所示的进程都进入了死锁的状态: 

进程C等待这资源T, 资源T被进程D占用着, 进程D又等待着由进程C占用的资源U。   

 这样两个进程都得等待下去, 也就是两个进程 在争夺 两个资源,最终形成了 ,谁都无法使用资源的状态。

进程对资源的请求,与 资源的占用模型,只要能形成环, 环上的所有进程都是死锁进程。

四、四种处理死锁的策略:

1.忽略该问题。  也许如果你忽略它,它也会忽略你

2.检测死锁并恢复。  让死锁发生,检测他们是否发生,一旦发生死锁,采取行动解决问题。

3.仔细对资源进行分配,动态地避免死锁。

4.通过破坏死锁的四个必要条件之一,防止死锁的产生。

五、经典的IPC问题     哲学家就餐问题

问题描述:

哲学家的生活中有两种交替活动时段:即吃饭和思考。   当一个哲学家觉得饿了时,他就试图分两次去取其左边和右边的叉子,就开始吃饭,吃完后放下叉子继续思考。

能为下图中五个哲学家,每一个哲学家写一段描述其行为的程序,且决不会死锁吗?

 现在操作系统 ,提供的一种可行的解决方案:

#define N       5              
#define LEFT    (i+N-1)%N      
#define RIGHT   (i+1)%N        
#define THINKING 0             
#define HUNGRY   1             
#define EATING   2             
typedef int  semaphore;        
int  state[N];                 
semaphore mutex = 1;           
semaphore s[N];                

void philosopher(int i)        
{
    while(true)                
    {
    }
}  

void take_forks(int i)         
{
    down(&mutex);              
    state[i] = HUNGRY;         
    test(i);                   
    up(&mutex);                
    down(&s[i]);               
}

void put_forks(i)              
{
    down(&mutex);              
    state[i] = THINKING;       
    test(LEFT);                
    test(RIGHT);               
    up(&mutex);                
}

void test(i)                   
{
    if(state[i] == HUNGRY && state[LEFT]!=EATING && state[RIGHT]!=EATING)
    {
        state[i] = EATING;
        up(&s[i]);
    }
}

算法中使用一个数组state跟踪每一个哲学家是在进餐、思考还是饥饿状态,  一个哲学家只有在两个邻居都没有进餐时,才允许进入到进餐状态。  

程序使用了一个信号量数组, 每个信号量对应一位哲学家,这样在所需的叉子被占用时,想进餐的哲学家就被阻塞。

注意,每个进程将过程philosopher作为主代码运行,而其他过程take_forks、put_forks 和 test 只是普通的过程,而非单独的进程。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/705187.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号