C语言实现操作系统银行家算法

来源:互联网 发布:超高清图片下载软件 编辑:程序博客网 时间:2024/05/18 03:24

#include <stdio.h>
#include <conio.h>
#include <stdlib.h>

#define RESOURCE_MAXNUM            3        //资源数
#define THREAD_MAXNUM            5        //进程数

//定义可利用资源向量
struct Available
{
    int available[RESOURCE_MAXNUM];
}res_ava;

//最大需求矩阵
struct Max
{
    int max[THREAD_MAXNUM][RESOURCE_MAXNUM];
}res_max;

//已分配矩阵
struct Allocation
{
    int allocation[THREAD_MAXNUM][RESOURCE_MAXNUM];
}res_all;

//需求矩阵
struct Need
{
    int need[THREAD_MAXNUM][RESOURCE_MAXNUM];
}res_nee;

//临时进程的资源分配序列
int tmpSequence[THREAD_MAXNUM];
//可能的一个安全序列
int secSequence[THREAD_MAXNUM];
//找到一个安全执行序列的标志
int isFindSecQue = 0;

//定义一系操作方法
//进行显式地初始化操作
void init();
//打印操作
void printInfo();
//输入操作
void input();
//检测条件Need = Max - Allocation
int check();
//测试可得到的资源能否江足要求
int check(int threadID,int need[THREAD_MAXNUM]);
//当前待分配的进程需求
void curThreadNeed();
//更新操作
void update(int thredID,int need[THREAD_MAXNUM]);
//释放操作
void release(int threadID);
//安全性算法
int security(int sequence[THREAD_MAXNUM]);
//回溯得到进程执行序列,并执行安全性算法
void backtrack(int i);
//交换数组中指定的两个值
void swapArray(int arr[THREAD_MAXNUM],int pos1,int pos2);
//拷贝数组
void copyArray(int arr1[THREAD_MAXNUM],int arr2[THREAD_MAXNUM]);

int main()
{
    init();
    input();
    int checkres = check();
    if(checkres == 0)
    {
        printf("输入有问题,确认后重新输入/n");
        exit(-1);
    }
    printInfo();
    curThreadNeed();
    printInfo();
    printf("执行安全性算法/nENTER键继续 .../n/n");
    getch();
    backtrack(0);
    if(isFindSecQue == 0)
        printf("未找到一个安全的进程执行序列/n");
    return 0;
}

void init()
{
    int i,j;
    for(i = 0;i < THREAD_MAXNUM; ++i)
    {
        for(j = 0;j < RESOURCE_MAXNUM; ++j)
        {
            res_all.allocation[i][j] = 0;
            res_max.max[i][j] = 0;
            res_nee.need[i][j] = 0;
        }
        tmpSequence[i] = i;
        secSequence[i] = i;
    }

    for(j = 0;j < RESOURCE_MAXNUM; ++j)
    {
        res_ava.available[j] = 0;
    }
}

void printInfo()
{
    int i,j;
    printf("**********************当前资源分配**********************/n");
    printf("最大需求矩阵/t/t|分配矩阵/t/t|需求矩阵 /n");
    for(i = 0;i < THREAD_MAXNUM; ++i)
    {
        for(j = 0;j < RESOURCE_MAXNUM; ++j)
        {
            printf("%d/t",res_max.max[i][j]);
        }
        for(j = 0;j < RESOURCE_MAXNUM; ++j)
        {
            printf("%d/t",res_all.allocation[i][j]);
        }
        for(j = 0;j < RESOURCE_MAXNUM; ++j)
        {
            printf("%d/t",res_nee.need[i][j]);
        }
        printf("/n");
    }
    printf("/n");
    printf("可利用资源向量/t/n");
    for(j = 0;j < RESOURCE_MAXNUM; ++j)
    {
        printf("%d/t",res_ava.available[j]);
    }
    printf("/n");

}

void input()
{
    int i,j;
    printf("输入当前可利用资源/n");
    for(j = 0;j < RESOURCE_MAXNUM; ++j)
    {
        scanf("%d",&res_ava.available[j]);
    }
    printf("输入分配矩阵 /n");
    for(i = 0;i < THREAD_MAXNUM; ++i)
    {
        for(j = 0;j < RESOURCE_MAXNUM; ++j)
        {
            scanf("%d",&res_all.allocation[i][j]);
        }
    }
    printf("输入最大需求矩阵/n");
    for(i = 0;i < THREAD_MAXNUM; ++i)
    {
        for(j = 0;j < RESOURCE_MAXNUM; ++j)
        {
            scanf("%d",&res_max.max[i][j]);
        }
    }
    printf("输入需求矩阵/n");
    for(i = 0;i < THREAD_MAXNUM; ++i)
    {
        for(j = 0;j < RESOURCE_MAXNUM; ++j)
        {
            scanf("%d",&res_nee.need[i][j]);
        }
    }
}

int check()
{
    int i,j;
    for(i = 0;i < THREAD_MAXNUM; ++i)
    {
        for(j = 0;j < RESOURCE_MAXNUM; ++j)
        {
            if(res_nee.need[i][j] != res_max.max[i][j] - res_all.allocation[i][j])
            {
                return 0;
            }
        }
    }
    return 1;
}

int check(int threadID,int need[THREAD_MAXNUM]){
    int i;
    for(i = 0;i<RESOURCE_MAXNUM; ++i)
    {
        //当前需求向量要小于可获得资源向量及相应需求向量
        if(need[i] > res_ava.available[i] || need[i] > res_nee.need[threadID][i])
            return 0;
    }
    return 1;
}

void curThreadNeed()
{
    printf("输入当前进程的编号及所需的资源向量/n");
    int need;
    scanf("%d",&need);
    int res_need[RESOURCE_MAXNUM];
    int i;
    for(i = 0;i < RESOURCE_MAXNUM; ++i)
    {
        scanf("%d",&res_need[i]);
    }
    printf("进程%d需要的资源向量为:/n",need);
    for(i = 0;i < RESOURCE_MAXNUM; ++i)
    {
        printf("%d/t",res_need[i]);
    }
    printf("/n");
    if(check(need,res_need) == 0)
    {
        printf("需求大于可获得的资源,请确定后再输入/n");
        exit(-1);
    }
    //更新操作
    update(need,res_need);
}

void update(int thredID,int need[THREAD_MAXNUM])
{
    int j;
    for(j = 0;j<RESOURCE_MAXNUM; ++j)
    {
        res_ava.available[j] -= need[j];
        res_nee.need[thredID][j] -= need[j];
        res_all.allocation[thredID][j] += need[j];
    }
}

void release(int threadID)
{
    int i;
    for(i = 0;i < RESOURCE_MAXNUM; ++i)
    {
        res_ava.available[i] += res_max.max[threadID][i];
    }
}

int security(int sequence[THREAD_MAXNUM])
{
    //工作向量
    int Work[RESOURCE_MAXNUM];
    int i;
    for(i = 0;i < RESOURCE_MAXNUM; ++i)
    {
        Work[i] = res_ava.available[i];
    }

    for(i = 0;i<THREAD_MAXNUM; ++i)
    {
        //判断当前能否分配资源
        int canAllFlag = 1;        //能分配的标志
        int j;
        for(j = 0; j< RESOURCE_MAXNUM; ++j)
        {
            if(res_nee.need[sequence[i]][j] > Work[j])
            {
                canAllFlag = 0;
                break;
            }
        }
        if(canAllFlag == 0)
            return 0;
        //释放资源操作
        for(j = 0; j< RESOURCE_MAXNUM; ++j)
        {
            Work[j] += res_all.allocation[sequence[i]][j];
        }
    }
    return 1;
}

void backtrack(int i)
{
    if(i >= THREAD_MAXNUM)
    {
        //若此序列为安全的序列
        if(security(tmpSequence) == 1)
        {
            isFindSecQue = 1;
            copyArray(secSequence,tmpSequence);
            printf("找到一个安全序列/n");
            int i;
            for(i = 0 ;i< THREAD_MAXNUM; ++i)
            {
                printf("%d/t",secSequence[i]);
            }
            printf("/n");
        }
    }
    int j;
    for(j = i;j<THREAD_MAXNUM; ++j)
    {
        swapArray(tmpSequence,i,j);
        backtrack(i+1);
        swapArray(tmpSequence,i,j);
    }
}

void swapArray(int arr[THREAD_MAXNUM],int pos1,int pos2)
{
    int tmp;
    tmp = arr[pos1];
    arr[pos1] = arr[pos2];
    arr[pos2] = tmp;
}

void copyArray(int arr1[THREAD_MAXNUM],int arr2[THREAD_MAXNUM])
{
    int i;
    for(i = 0;i < THREAD_MAXNUM; ++i)
    {
        arr1[i] = arr2[i];
    }
}
/*
输入测例
3 3 2
0 1 0
2 0 0
3 0 2
2 1 1
0 0 2
7 5 3
3 2 2
9 0 2
2 2 2
4 3 3
7 4 3
1 2 2
6 0 0
0 1 1
4 3 1
1
1 0 2
*/