死锁 —— 银行家算法

死锁: 是指两个或两个以上的进程在执行过程中,因争夺资源而造成的一种互相等待的现象,若无外力作用,它们都将无法推进下去。此时称系统处于死锁状态或系统产生了死锁,这些永远在互相等待的进程称为死锁进程。 由于资源占用是互斥的,当某个进程提出申请资源后,使得有关进程在无外力协助下,永远分配不到必需的资源而无法继续运行,这就产生了一种特殊现象:死锁。

虽然进程在运行过程中,可能发生死锁,但死锁的发生也必须具备一定的条件,死锁的发生必须具备以下四个必要条件。
1)互斥条件:指进程对所分配到的资源进行排它性使用,即在一段时间内某资源只由一个进程占用。如果此时还有其它进程请求资源,则请求者只能等待,直至占有资源的进程用毕释放。
2)请求和保持条件:指进程已经保持至少一个资源,但又提出了新的资源请求,而该资源已被其它进程占有,此时请求进程阻塞,但又对自己已获得的其它资源保持不放。
3)不剥夺条件:指进程已获得的资源,在未使用完之前,不能被剥夺,只能在使用完时由自己释放。
4)环路等待条件:指在发生死锁时,必然存在一个进程——资源的环形链,即进程集合{P0,P1,P2,···,Pn}中的P0正在等待一个P1占用的资源;P1正在等待P2占用的资源,……,Pn正在等待已被P0占用的资源。
***********************************************************************************************************************************************************************************
银行家算法:避免思索的发生。

算法思想:

       1、假分配检测:Request < Need

                            Request < Available

       2、安全序列检测算法

实例列举:

  某系统有R1,R2,R3共3中资源,在T0时刻P0,P1,P2,P3和P4这5个进程对资源的占用和需求情况如下表1,此时系统的可用资源向量为(3,3,2)。试问:

1、T0时刻系统是否存在安全序列?

2、P1请求资源:P1发出请求向量Request(1,0,2),系统是否接受该请求?请使用银行家算法检查

3、P4请求资源:P4发出请求向量Request(3,3,0),系统按银行家算法检查.

4、P0请求资源:P0发出请求向量Request(0,2,0),系统按银行家算法检查.

      表1 T0时刻的资源分配表

  MAX Allocation Need Available
P0            7 5 3         0 1 0         7 4 3          3 3 2        
P1 3 2 2   2 0 0 1 2 2       
P2 9 0 2 3 0 2 6 0 0  
P3 2 2 2 2 1 1 0 1 1  
P4 4 3 3 0 0 2 4 3 1  

 

an:

  1、T0时刻系统是否存在安全序列?

    Available > Need1 ----> 可用资源分配给P1,直到P1进程执行完成,然后Available = Available + Allocation1 = (5,3,2)

           Available > Need3 -----> 可用资源分配给P3,直到P3进程执行完成,然后Available = Available + Allocation3 = (7,4,3)

    Available> Need4.....

        得到安全序列为:P1,P3,P4,P2,P0

  2、P1请求资源:P1发出请求向量Request(1,0,2),系统是否接受该请求?请使用银行家算法检查

   第一步(假分配检查):把Request分配给P1,必须满足Request要小于Available,Request要小于Need。

                       Request(1,0,2)< Available(3,3,2)

                       Request(1,0,2)< Need(1,2,2)

        因为满足第一步检查,进入第二层检查(安全序列检查)。

   第二步(安全序列检查):建立安全性检查表

  Work Need Allocation Work+Allocation Finish
P1 2 3 0 0 2 0 3 0 2    
           
           
           
           

  如果 Work > Need ,那么执行Work+Allocation,得到:                

  Work Need Allocation Work+Allocation Finish
P1   2 3 0 0 2 0     3 0 2  5 3 2  true
  5 3 2            
           
           
           

   找到Need

   这里我们找到了P3进程。修改安全序列检查表:

  Work Need Allocation Work+Allocation Finish
P1   2 3 0 0 2 0     3 0 2  5 3 2  true
P3 5 3 2     0 1 1 2 1 1  7 4 3  true
  7 4 3        
           
           

  这样一直执行到所有的进程到完成,以完成该安全序列检查表:

  Work Need Allocation Work+Allocation Finish
P1   2 3 0 0 2 0     3 0 2  5 3 2  true
P3 5 3 2     0 1 1 2 1 1  7 4 3  true
P4 7 4 3 4 3 1 0 0 2  7 4 5  true
P0 7 4 5 7 4 3 0 1 0  7 5 5  true
P2 7 5 5 6 0 0 3 0 2 10 5 7  true

      这样就找到了整个安全序列为:P1,P3,P4,P0,P2

    3、4小问也是同样的解题过程。这里不赘述...

****************************************************************************************************

算法流程图:

1.初始化算法流程图:
死锁 —— 银行家算法_第1张图片
2.银行家算法流程图:
死锁 —— 银行家算法_第2张图片
 3.安全性算法流程图:
死锁 —— 银行家算法_第3张图片
算法设计:
1.设进程i提出请求Request[n],则银行家算法按如下规则进行判断。
(1)如果Request[n]>Need[i,n],则报错返回。
(2)如果Request[n]>Available,则进程i进入等待资源状态,返回。
(3)假设进程i的申请已获批准,于是修改系统状态:
    Available=Available-Request
    Allocation=Allocation+Request
    Need=Need-Request
(4)系统执行安全性检查,如安全,则分配成立;否则试探险性分配作废,系统恢复原状,进程等待。
2.安全性检查
(1)设置两个工作向量Work=Available;Finish =False
(2)从进程集合中找到一个满足下述条件的进程,
   Finish =False
   Need<=Work
   如找到,执行(3);否则,执行(4)
(3)设进程获得资源,可顺利执行,直至完成,从而释放资源。
    Work=Work+Allocation
    Finish=True
    GO TO 2
(4)如所有的进程Finish =true,则表示安全;否则系统不安全。
数据结构:
假设有M个进程N类资源,则有如下数据结构:
#define W 10
#define R 20
int A ;                      //总进程数
int B ;                     //资源种类
int ALL_RESOURCE[W];        //各种资源的数目总和
int MAX[W] ;             //M个进程对N类资源最大资源需求量
int AVAILABLE ;          //系统可用资源数
int ALLOCATION[W] ;      //M个进程已经得到N类资源的资源量
int NEED[W] ;            //M个进程还需要N类资源的资源量
int Request ;            //请求资源个数
主要函数说明
void showdata();           //主要用来输出资源分配情况
void changdata(int);       //主要用来输出资源分配后后的情况
void rstordata(int);       //用来恢复资源分配情况,如:银行家算法时,由于分配不安全则要恢复资源分配情况
int chkerr(int);           //银行家分配算法的安全检查
void bank()   ;             //银行家算法

数据结构分析:
假设有M个进程N类资源,则有如下数据结构:
#define W 10
#define R 20
int A ;                      //总进程数
int B ;                     //资源种类
int ALL_RESOURCE[W];        //各种资源的数目总和
int MAX[W] ;             //M个进程对N类资源最大资源需求量
int AVAILABLE ;          //系统可用资源数
int ALLOCATION[W] ;      //M个进程已经得到N类资源的资源量
int NEED[W] ;            //M个进程还需要N类资源的资源量
int Request ;            //请求资源个数
代码如下:
using namespace std;
#define MAXPROCESS 50                        /*最大进程数*/
#define MAXRESOURCE 100                        /*最大资源数*/
int AVAILABLE[MAXRESOURCE];                    /*可用资源数组*/
int MAX[MAXPROCESS][MAXRESOURCE];            /*最大需求矩阵*/
int ALLOCATION[MAXPROCESS][MAXRESOURCE];    /*分配矩阵*/
int NEED[MAXPROCESS][MAXRESOURCE];            /*需求矩阵*/
int REQUEST[MAXPROCESS][MAXRESOURCE];        /*进程需要资源数*/
bool FINISH[MAXPROCESS];                        /*系统是否有足够的资源分配*/
int p[MAXPROCESS];                             /*记录序列*/
int m,n;                                    /*m个进程,n个资源*/
void Init();
bool Safe();
void Bank();
int main()
{
    Init();
    Safe();
    Bank();
}
void Init()                /*初始化算法*/
{
    int i,j;
    cout<<"\t---------------------------------------------------"<>m;
    cout<<"请输入资源的种类:";
    cin>>n;
    cout<<"请输入每个进程最多所需的各资源数,按照"<>MAX[j];
    cout<<"请输入每个进程已分配的各资源数,也按照"<>ALLOCATION[j];
            NEED[j]=MAX[j]-ALLOCATION[j];
            if(NEED[j]<0)
            {
                cout<<"您输入的第"<>AVAILABLE;
    }
}
void Bank()                /*银行家算法*/
{
    int i,cusneed;
    char again;
    while(1)
    {
        cout<<"请输入要申请资源的进程号(注:第1个进程号为0,依次类推)"<>cusneed;
        cout<<"请输入进程所请求的各资源的数量"<>REQUEST[cusneed];
        }
        for(i=0;iNEED[cusneed])
            {
                cout<<"您输入的请求数超过进程的需求量!请重新输入!"<AVAILABLE)
            {
                cout<<"您输入的请求数超过系统有的资源数!请重新输入!"<>again;
        if(again=='y'||again=='Y')
        {
            continue;
        }
        break;
        }
}
bool Safe()                                    /*安全性算法*/
{
    int i,j,k,l=0;
    int Work[MAXRESOURCE];                    /*工作数组*/
    for(i=0;iWork[j])
                {
                    break;
                }
            }
            if(j==n)
            { 
                FINISH=true;
                for(k=0;k";
                }
            }
            cout<<""<

结果:
死锁 —— 银行家算法_第4张图片

你可能感兴趣的:(操作系统)