编程语言
首页 > 编程语言> > 死锁的四个必要条件 & 死锁避免算法(银行家算法)

死锁的四个必要条件 & 死锁避免算法(银行家算法)

作者:互联网

一、死锁

1.1产生死锁的原因:

(1) 因为系统资源不足。
(2) 进程运行推进的顺序不合适。
(3) 资源分配不当等。
如果系统资源充足,进程的资源请求都能够得到满足,死锁出现的可能性就很低,否则就会因争夺有限的资源而陷入死锁。其次,进程运行推进顺序与速度不同,也可能产生死锁。

1.2 产生死锁的四个必要条件

(1) 互斥条件:一个资源每次只能被一个进程使用。
(2) 占有且等待:一个进程因请求资源而阻塞时,对已获得的资源保持不放。
(3)不可强行占有:进程已获得的资源,在末使用完之前,不能强行剥夺。
(4) 循环等待条件:若干进程之间形成一种头尾相接的循环等待资源关系。
这四个条件是死锁的必要条件,只要系统发生死锁,这些条件必然成立,而只要上述条件之一不满足,就不会发生死锁。

1.3 死锁的解除与预防

理解了死锁的原因,尤其是产生死锁的四个必要条件,就可以最大可能地避免、预防和解除死锁。所以,在系统设计、进程调度等方面注意如何不让这四个必要条件成立,如何确
定资源的合理分配算法,避免进程永久占据系统资源。此外,也要防止进程在处于等待状态
的情况下占用资源。因此,对资源的分配要给予合理的规划

1.4 处理死锁的基本方法:

1.4.1死锁预防:破坏死锁的四个条件中的一个或几个。

(1)互斥:它是设备的固有属性所决定的,不仅不能改变,还应该加以保证。

(2)占有且等待:

为预防占有且等待条件,可以要求进程一次性的请求所有需要的资源,并且阻塞这个进程直到所有请求都同时满足。这个方法比较低效。

(3)不可抢占:

预防这个条件的方法:

(4)循环等待:通过定义资源类型的线性顺序来预防。

1.4.2 死锁避免:

(1)两种死锁避免算法:

*进程启动拒绝:如果一个进程的请求会导致死锁,则不启动该进程。

*资源分配拒绝:如果一个进程增加的资源请求会导致死锁,则不允许此分配(银行家算法)。

摘自:https://blog.csdn.net/rabbit_in_android/article/details/50530960

二、银行家算法

银行家算法的实质就是要设法保证系统动态分配资源后不进入不安全状态,以避免可能产生的死锁。即没当进程提出资源请求且系统的资源能够满足该请求时,系统将判断满足此次资源请求后系统状态是否安全,如果判断结果为安全,则给该进程分配资源,否则不分配资源,申请资源的进程将阻塞。

银行家算法的执行有个前提条件,即要求进程预先提出自己的最大资源请求,并假设系统拥有固定的资源总量。下面介绍银行家算法所用的主要的数据结构。
在这里插入图片描述
在这里插入图片描述

2.2. 具体实例

假定操作系统中的4个进程P1、P2、P3、P4和3类资源R1、R2、R3(资源数量分别为9、3、6),在t0时刻的资源分配情况如表2-1:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

2.3.测试代码

#include<iostream>
using namespace std;
// p 进程数,r资源种类
int p ;
int r ;
int maxs[10][10]; //最大需求矩阵
int allocation[10][10]; //分配矩阵
int need[10][10];   //需求矩阵
int available[10]; //可用资源向量
int request[10];   //请求向量当前进程对各类资源的申请量,算法的入口参数
//输入函数
void infInput()
{
    int i,j;
    cout<<"请输入最大需求矩阵max\n";
    for(i=0; i<p; i++)
    {
        for(j=0; j<r; j++)
        {
            cin>>maxs[i][j];
        }
    }
    cout<<"请输入分配矩阵allocation\n";
    for(i=0; i<p; i++)
    {
        for(j=0; j<r; j++)
        {
            cin>>allocation[i][j];
        }
    }
    cout<<"请输入需求矩阵need\n";
    for(i=0; i<p; i++)
    {
        for(j=0; j<r; j++)
        {
            cin>>need[i][j];
        }
    }
    cout<<"请输入可用资源向量available\n";
    for(i=0; i<r; i++)
    {
        cin>>available[i];
    }
}

//比较函数
//比较进程为m中的元素全大于n中的元素返回1,否则返回0
int compare(int m[],int n[])
{
    int i;
    for(i=0; i<r; i++)
    {
        if(m[i]<n[i])
        {
            return 0;
        }
    }
    return 1;
}


//安全性检验函数,检测是否存在安全序列
int stest()
{
    int i,j,k,l,flag=0;
    int finish[p];
    int work[r];
    for(i=0; i<p; i++)
    {
        finish[i]=0;
        //vis为1即表示available满足第i进程的资源需要
    }
    for(i=0; i<r; i++)
    {
        work[i]=available[i];
    }
    cout<<"分配序列:\n";
    cout<<"            allocation            need              avilable"<<endl;
    for(k=0; k<p; k++)
    {
        for(i=0; i<p; i++)
        {
            if(finish[i]==1)
            {
                continue;
            }
            else
            {
                if(compare(work,need[i]))//available>=need
                {
                    finish[i]=1;
                    cout<<'\n'<<"进程"<<i+1<<'\t';
                    flag=1;
                    for (j =0; j<r; j++)
                    {
                        printf("  %2d ", allocation[i][j]);
                    }
                    cout<<"     ";
                    for (j = 0; j < r; j++)
                    {
                        printf("  %2d ", need[i][j]);
                    }
                    cout<<"     ";
                    for (j = 0; j <r; j++)
                    {
                        printf("  %2d ", work[j] +allocation[i][j]);
                    }
                    for(l=0; l<r; l++)
                    {
                        work[l]=work[l]+allocation[i][l];
                        //进程完成,释放资源
                    }
                    break;
                }
            }
            if(flag==1)
            {
                break;
            }
        }
    }
    cout<<'\n';
    for(l=0; l<p; l++)
    {
        if(finish[l]==0)
        {
            return 0;//不存在安全序列
        }
    }
    return 1;//存在安全序列
}

//申请进程后的安全性检验函数

void rtest(int n)
{
    int j;
    //n=n-1;
    if(compare(available,request)&&compare(need[n-1],request))//available>=request 并且 need >=request
    {
        for(j=0; j<r; j++)
        {
            allocation[n-1][j]=allocation[n-1][j]+request[j];
            need[n-1][j]=need[n-1][j]-request[j];
            available[j]=available[j]-request[j];
        }
        if(stest())
        {
            cout<<"允许"<<n<<"进程申请资源!\n";
        }
        else
        {
            cout<<"不允许"<<n<<"进程申请资源!\n";
            for(j=0; j<r; j++)
            {
                allocation[n-1][j]=allocation[n-1][j]-request[j];
                need[n-1][j]=need[n-1][j]+request[j];
                available[j]=available[j]+request[j];
            }
        }
    }
    else
    {
        cout<<"申请资源量越界!\n";
    }
}

int main()
{
    int i,n;       //n-第n个资源申请
    cout<<"请输入进程数:";
    cin>>p;
    cout<<"请输入资源种类数:";
    cin>>r;
    //默认状态4、3
    infInput();//输入函数
    if(stest()==1)
    {
        cout<<"存在安全序列,初始状态安全。\n";
    }
    else
    {
        cout<<"不存在安全序列,初始状态不安全。\n";
    }
    cout<<"请输入发出请求向量request的进程编号:";
    cin>>n;
    cout<<"请输入请求向量request\n";
    for(i=0; i<r; i++)
    {
        cin>>request[i];
    }
    rtest(n);
    return 0;
}
/*
4
3
3 2 2
6 1 3
3 1 4
4 2 2
1 0 0
5 1 1
2 1 1
0 0 2
2 2 2
1 0 2
1 0 3
4 2 0
1 1 2
*/

摘自:https://www.cnblogs.com/wkfvawl/p/11929508.html

标签:cout,int,request,算法,死锁,必要条件,进程,资源
来源: https://blog.csdn.net/s11show_163/article/details/113357395