操作系统课程设计银行家算法

银行家算法是 Dijkstra在1965年提出的一种避免死锁的算法。银行家算法陈述如下:
1)   当一个进程提出一个资源的请求时,假定分配给它,并调用检查系统状态安全性的算法。如果系统是安全的,则对申请者的假分配变为实际的分配。否则,推迟它的请求,让其阻塞等待。
2)   检查系统状态安全性的算法。根据系统剩余的资源情况,银行家进行检查,看满足请求者的要求后,是否仍是系统中的所有进程都能正常完成(即能找到一个进程完成序列)。若能,系统是安全的。否则,系统是不安全的。
银行家算法主要如下:
输入:资源个数 m、进程个数n、最大请求矩阵max、分配矩阵allocation
输出:进程运行情况和安全状况提示(如果安全,输出一个可能的进程完成序列)
主要算法:
1)   初始化,输入各个参数,初始化各变量
 
2)   判断系统安全性
程序中安全性算法的描述如下:
a.   设置如下两个工作向量:
Work:表示系统可提供给进程继续运行的各类资源的空闲资源数目,它含有m个元素,执行安全性算法开始时,Work=Available。
Finish:表示系统是否有足够的资源分配给进程,使之运行完成。开始时,Finish[i]=false;当有足够的资源分配给进程Pi时,令Finish[i]=true。
b.   从进程集合中找到一个能满足下列条件的进程:
Finish[i]= false;
Need[i] <= Work;
如果找到了就执行步骤c,否则执行步骤d。
c.   当进程Pi获得资源后,可执行直到完成,并释放出分配给它的资源,故应执行
Work = Allocation[i]+Work;
Finish[i]=true;
然后转向b。
d.   若所有进程中的Finish[i]都是true,则表示系统处于安全状态;否则,系统处于不安全状态。
 
3)   当系统请求资源时,调用系统状态安全性算法
系统状态安全性算法:
当某一进程提出资源申请时,系统须做出判断,能否将所申请资源分配给该进程。设Request[i]是进程Pi的请求向量,Request[i][j]=k表示进程Pi请求分配 j类资源有k个。当Pi发出资源请求后,系统按照下述步骤进行检查:
a. 如果Request[i]<= Need[i],则转向 b;否则出错,因为进程所需要的资源数已超过它所宣布的最大值;
b.  如果Request[i]<=Available,则转向步骤 c;否则,表示系统中尚无足够的资源满足进程Pi的申请,让进程Pi等待。
c. 假设系统把申请的资源分配给进程Pi,则对应下面的数据结构进行修改:
Available= Available-Request[i];
            Allocation[i]= Allocation[i]+Request[i];
Need[i]= Need[i]-Request[i];
d. 系统执行安全性算法,检查此次资源分配后,系统是否处于安全状态。若安全,就将资源分配给Pi,满足其资源申请要求;否则,让进程等待,并恢复原来的资源分配状态。
 
数据结构:
class bank
{
private:
    int m;                //资源数量
    int n;                //进程数量
    int available[M];     //可利用资源向量
    int max[M][N];        //最大需求矩阵
    int allocation[M][N]; //分配矩阵
    int need[M][N];       //需求矩阵
public:
    bool Initilize();     //初始化各变量
    bool IsSafe();        //检查系统是否安全
    bool Resoure_allocate();//分配资源
    bool IsFinish();      //检查系统是否运行完毕
};
 
 
测试用例:
本测试用例为《操作系统原理教程(第二版)》 P62页用例,先给P2分配一个打印机,分配成功,然后分配给P5一台打印机,分配失败,然后按照P4,P1,P5,P2,P3执行系统。
 
Available=( 1,0,2,0)

进程
磁带机
绘图机
打印机
光驱
P1
3
0
1
1
P2
0
1
0
0
P3
1
1
1
0
P4
1
1
0
1
P5
0
0
0
0
进程当前的分配矩阵 Allocation

进程
磁带机
绘图机
打印机
光驱
P1
1
1
0
0
P2
0
1
1
2
P3
3
1
0
0
P4
0
0
1
0
P5
2
1
1
0
进程当前的剩余请求矩阵 Need

进程
磁带机
绘图机
打印机
光驱
P1
4
1
1
1
P2
0
2
1
2
P3
4
2
1
0
P4
1
1
1
1
P5
2
1
1
0
各个进程的最大请求矩阵 Max
测试数据:(直接复制到终端中即可)
4
5
4 1 1 1
0 2 1 2
4 2 1 0
1 1 1 1
2 1 1 0
3 0 1 1
0 1 0 0
1 1 1 0
1 1 0 1
0 0 0 0
1 0 2 0
1
2
1
4
2
1
3
2
1
0
0
1
0
1
1
4
0
2
4
1
1
4
2
1
1
1
1
1
3
2
2
0
3
2
1
1
运行结果:
输入资源数量: 4
输入进程数量: 5
输入最大请求矩阵 5X4
4 1 1 1
0 2 1 2
4 2 1 0
1 1 1 1
2 1 1 0
输入分配矩阵 5X4
3 0 1 1
0 1 0 0
1 1 1 0
1 1 0 1
0 0 0 0
输入可利用资源向量 1X4
1 0 2 0
安全序列是
3 0 1 2 4
输入运行进程号 :1
请求资源号: 2
请求数量: 1
安全序列是
3 0 1 2 4
输入运行进程号 :4
请求资源号: 2
请求数量: 1
没有安全序列
系统不安全,等待
输入运行进程号 :3
请求资源号: 2
请求数量: 1
安全序列是
0 1 2 4
进程 3运行完毕
输入运行进程号 :0
请求资源号: 0
请求数量: 1
安全序列是
0 1 2 4
输入运行进程号 :0
请求资源号: 1
请求数量: 1
安全序列是
1 2 4
进程 0运行完毕
输入运行进程号 :4
请求资源号: 0
请求数量: 2
安全序列是
1 2 4
输入运行进程号 :4
请求资源号: 1
请求数量: 1
安全序列是
4 1 2
输入运行进程号 :4
请求资源号: 2
请求数量: 1
安全序列是
1 2
进程 4运行完毕
输入运行进程号 :1
请求资源号: 1
请求数量: 1
安全序列是
1 2
输入运行进程号 :1
请求资源号: 3
请求数量: 2
安全序列是
2
进程 1运行完毕
输入运行进程号 :2
请求资源号: 0
请求数量: 3
安全序列是
2
输入运行进程号 :2
请求资源号: 1
请求数量: 1
安全序列是
 
进程 2运行完毕
所有进程执行完毕

源代码:
    #include <iostream>  
    #include <cstdlib>  
    #define M 16  
    #define N 16  
    using namespace std;  
     
    class bank  
    {  
    private:  
        int m;                //资源数量  
        int n;                //进程数量  
        int available[M];     //可利用资源向量  
        int max[M][N];        //最大需求矩阵  
        int allocation[M][N]; //分配矩阵  
        int need[M][N];       //需求矩阵  
    public:  
        bool Initilize();     //初始化各变量  
        bool IsSafe();        //检查系统是否安全  
        bool Resoure_allocate();//分配资源  
        bool IsFinish();      //检查系统是否运行完毕  
    };  
     
    int main()  
    {  
        bank process;  
     
        if (!process.Initilize())   //初始化  
        {  
            cout<<"输入错误"<<endl;  
        }  
     
        if (!process.IsSafe())      //检查系统运行初是否安全  
        {  
            return 0;  
        }  
     
        while (true)  
        {  
            process.Resoure_allocate();     //根据各进程需要分配资源  
            if (process.IsFinish())         //检查系统是否执行完毕  
            {  
                cout<<"所有进程执行完毕"<<endl;  
                break;  
            }  
        }  
        system("PAUSE");  
        return 0;  
    }  
     
    bool bank::Initilize()  
    {  
        int i,j;  
        cout<<"输入资源数量:";  
        cin>>m;  
        cout<<"输入进程数量:";  
        cin>>n;  
        cout<<"输入最大请求矩阵 "<<n<<"X"<<m<<endl;  
        for (i = 0; i < n; i++)  
        {  
            for (j = 0; j < m; j++)  
            {  
                cin>>max[i][j];  
            }  
        }  
        cout<<"输入分配矩阵 "<<n<<"X"<<m<<endl;  
        for (i = 0; i < n; i++)  
        {  
            for (j = 0; j < m; j++)  
            {  
                cin>>allocation[i][j];  
            }  
        }  
        for (i = 0; i < n; i++)  
        {  
            for (j = 0; j < m; j++)  
            {  
                need[i][j]=max[i][j]-allocation[i][j];  
                if (need[i][j] < 0)  
                {  
                    return false;  
                }  
            }  
        }  
        cout<<"输入可利用资源向量 "<<1<<"X"<<m<<endl;  
        for (i = 0; i < m; i++)  
        {  
            cin>>available[i];  
            if (available[i] < 0)  
            {  
                return false;  
            }  
        }  
        return true;  
    }  
     
    bool bank::IsSafe()  
    {  
        int i,j,k,result[N],work[M],finish[N];  
        for (i = 0; i < m; i++)  
        {  
            work[i]=available[i];  
        }  
        for (i = 0; i < n; i++)                 //标识变量初始化  
        {  
            finish[i]=false;  
        }  
        for (i = 0, k = 0; i < n; i++)  
        {  
            if (!finish[i])  
            {  
                for (j = 0; j < m; j++)  
                {  
                    if (need[i][j] > work[j])      //目前无法满足该进程  
                    {  
                        break;  
                    }  
                }  
     
                if (j == m)                     //可以满足该进程  
                {  
                    result[k++]=i;  
                    for (j = 0; j < m; j++) //将现有可用资源数加上第i进程已经分配了的  
                    {  
                        work[j]+=allocation[i][j];  
                    }  
                    finish[i]=true;  
                    i=-1;                       //从头扫描  
                }  
            }  
        }  
        for (i = 0; i < n; i++)  
        {  
            if (!finish[i])  
            {  
                cout<<"没有安全序列"<<endl;  
                return false;  
            }  
        }  
        cout<<"安全序列是"<<endl;  
        for (i = 0; i < n; i++)  
        {  
            for ( j = 0; j < m; j++)            //如果进程已经执行完毕,则安全序列中不再输出  
            {  
                if (need[result[i]][j] != 0)  
                {  
                    break;  
                }  
            }  
            if (j == m)  
            {  
                continue;  
            }  
            cout<<result[i]<<" ";  
        }  
        cout<<endl;  
        return true;  
    }  
     
    bool bank::Resoure_allocate()  
    {  
        int i,process_id,source_id,amount;  
        cout<<"输入运行进程号:";  
        cin>>process_id;  
        cout<<"请求资源号:";  
        cin>>source_id;  
        cout<<"请求数量:";  
        cin>>amount;  
     
        if (amount > need[process_id][source_id])  
        {  
            cout<<"请求不合法,终止运行"<<endl;  
            return false;  
        }  
     
        if (amount > available[source_id])  
        {  
            cout<<"请求无法满足,等待"<<endl;  
            return false;  
        }  
     
        available[source_id]-=amount;                   //假定分配资源  
        allocation[process_id][source_id]+=amount;  
        need[process_id][source_id]-=amount;  
     
        if (!IsSafe())                                  //检查系统是否安全  
        {  
            available[source_id]+=amount;  
            allocation[process_id][source_id]-=amount;  
            need[process_id][source_id]+=amount;  
            cout<<"系统不安全,等待"<<endl;  
            return false;  
        }  
     
        for ( i = 0; i < m; i++)                        //查看进程是否执行完毕  
        {  
            if (allocation[process_id][i] != max[process_id][i])  
            {  
                break;  
            }  
        }  
     
        if (i == m)                                     //进程执行完毕  
        {  
            for ( i = 0; i < m; i++)  
            {  
                available[i]+=allocation[process_id][i];  
                allocation[process_id][i]=0;  
                need[process_id][i]=0;  
            }  
            cout<<"进程"<<process_id<<"运行完毕"<<endl;  
        }  
        return true;  
    }  
     
    bool bank::IsFinish()  
    {  
        int i,j,finish[N];  
     
        for ( i = 0; i < n; i++)  
        {  
            finish[i]=false;  
        }  
     
        for ( i = 0; i < n; i++)  
        {  
            for ( j = 0; j < m; j++)  
            {  
                if (need[i][j] != 0)  
                {  
                    break;  
                }  
            }  
            if (j == m)  
            {  
                finish[i]=true;  
            }  
        }  
     
        for ( i = 0; i < n; i++)  
        {  
            if (finish[i] == false)  
            {  
                break;  
            }  
        }  
        if (i != n)  
        {  
            return false;  
        }  
        return true;  
    }  


文章来自: http://curely.blog.51cto.com/1627940/803342

你可能感兴趣的:(操作系统课程设计银行家算法)