操作系统:Banker’s Algorithm

#include <bits/stdc++.h>
#include <pthread.h>
#include <unistd.h>
#include <windows.h>

using namespace std;

int available[maidn]={100,100,100,100}; // 可用资源
int maximum[maidn][maidn]; // 最大需求
int allocation[maidn][maidn]; // 已用资源
int need[maidn][maidn]; // 还需要的资源
int work[maidn]; // 目前可用资源
bool finish[maidn]; // 当前进程是否完成
int n=4,m,id; // 系统资源种类数,总进程数,进程号
int restm; // 剩余执行线程数
int zyzs[maidn]={100,100,100,100}; // 系统资源总数
int vis[15]; // 标记访问

pthread_mutex_t mutex;// 互斥信号量
pthread_cond_t cd;// 条件变量

// 安全性检查
int safecheck(int id) {
    int cmt[15]; // 线程安全顺序
    int favailable[maidn]; // 用一个镜像数组检测安全
    for(int i=0;i<n;i++) {
        favailable[i]=available[i];
    }
    int f=0;
    memset(vis,0,sizeof(vis));
    while(f<restm) {
        // 当目前判断数小于剩下线程数时
        bool flag=0;
        for(int i=0;i<m;i++) {
            if(!finish[i]&&!vis[i]) {
                int flag2=0;
                for(int j=0;j<n;j++) {
                    if(need[i][j]>favailable[j]) {
                        flag2=1;
                        break;
                    }
                }
                if(!flag2) { // 若该进程所需资源小于可用资源
                    flag=1;
                    vis[i]=1;
                    cmt[f++]=i;
                    for(int j=0;j<n;j++) {
                        favailable[j]+=allocation[i][j];
                    }
                }
            }
        }
        if(!flag) { // 若没有可运行的进程,则停止
            break;
        }
    }
    if(f==restm) {
        cout<<"系统处于安全状态,以下为安全序列: "<<endl;
        for(int i=0;i<f;i++) {
            cout<<cmt[i]+1<<" ";
        }
        cout<<endl<<endl;
        return 1;
    }
    else {
        cout<<"此时系统不安全,线程 "<<id+1<<" 将被阻塞!"<<endl;
        // 等到下次available更新再将该进程唤醒
        return 0;
    }
}

// 判断进程id对资源res的请求
int banker(int id,vector<int>res) {
    for(int i=0;i<res.size();i++) {
        int k=res[i];
        if(k<=need[id][i]) {
            // 进程请求资源数大于可用资源数,进程堵塞
            if(k>available[i]) {
                cout<<"线程 "<<id+1<<" 请求的 "<<i+1<<" 类资源大于该类资源可用数目!"<<endl;
                return 1;
            }
        }
        else {
            // 进程申请资源大于系统资源数,重新申请
            cout<<"线程 "<<id+1<<" 请求的 "<<i+1<<" 类资源大于该类资源总数!"<<endl;
            return 2;
        }
    }
    // 移动资源
    for(int i=0;i<res.size();i++) {
        int k=res[i];
        available[i]-=k;
        allocation[id][i]+=k;
        need[id][i]-=k;
    }
    // 检测安全,若无法分配,则先阻塞
    if(!safecheck(id)) {
        for(int i=0;i<res.size();i++) {
            int k=res[i];
            available[i]+=k;
            allocation[id][i]-=k;
            need[id][i]+=k;
        }
        return 3;
    }
    cout<<"线程 "<<id+1<<" 获得资源: "<<endl<<" | ";
    for(int i=0;i<res.size();i++) {
        cout<<"第 "<<i+1<<" 类: "<<res[i]<<" | ";
    }
    cout<<endl<<endl;
    return 0;
}

void init() {
    cout<<"系统资源种类总数: " <<n<<endl;
    cout<<n<<" 种资源总数: "<<endl;
    for(int i=0;i<n;i++) {
        cout<<available[i]<<" ";
    }
    cout<<endl<<endl;
    m=rand()%6+5;
    restm=m;
    cout<<"进程数: "<<m<<endl;
    cout<<m<<" 行 "<<n<<" 列代表 "<<m<<" 个进程对 "<<n<<" 种资源的最大需求: "<<endl;
    for(int i=0;i<m;i++) {
        for(int j=0;j<n;j++) {
            maximum[i][j]=rand()%101;
            need[i][j]=maximum[i][j];
            cout<<maximum[i][j]<<" ";
        }
        cout<<endl;
    }
    cout<<endl;
}

void *thyid(void *arg) {
    int id=(int) arg;

    // 随机请求资源
    vector<int>res;
    for(int i=0;i<n;i++) {
        if(need[id][i]==0) {
            res.push_back(0);
        }
        else {
            res.push_back(rand()%(need[id][i]+1));
        }
    }
    bool isfinish=0; // flag
    while(1) {
        pthread_muteid_lock(&mutex); // 加锁
        isfinish=0;
        // 判断该线程是否已经完成资源分配
        for(int i=0;i<n;i++) {
            if(need[id][i]!=0) {
                isfinish=1;
                break;
            }
        }
        // 资源完成分配
        if(!isfinish) {
            cout<<"线程 "<<id+1<<" 完成分配,程序继续执行"<<endl;
            Sleep(rand()%101);
            cout<<"线程 "<<id+1<<" 执行完毕"<<endl<<endl;
            restm--;
            finish[id]=1; // 该线程执行完成
            // 资源回收
            for(int i=0;i<n;i++) {
                available[i]+=allocation[id][i];
                cout<<"线程 "<<id+1<<" 释放资源 "<<i+1<<endl;
                Sleep(rand()%101);
                allocation[id][i]=0;
            }
            pthread_cond_broadcast(&cd); // 唤醒所有在cd,mutex中wait的线程
            pthread_muteid_unlock(&mutex); // 解锁
            pthread_eidit(NULL); // 退出该线程
        }
        int chk=banker(id,res);
        if(chk==1||chk==3) {
            // 系统不安全,或者所需资源大于系统资源,则先线程阻塞
            pthread_cond_wait(&cd, &mutex);
        }
        else if(chk==0||chk==2) {
            // 分配成功,或者得重新分配
            res.clear();
            for(int i=0;i<n;i++) {
                if(need[id][i]==0) {
                    res.push_back(0);
                }
                else {
                    res.push_back(rand()%(need[id][i]+1));
                }
            }
        }
        Sleep(rand()%101);
        pthread_muteid_unlock(&mutex); // 解锁
    }
}

int main() {
    //ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
    srand(time(NULL));
    pthread_t td[maidn]; // 线程
    pthread_muteid_init(&mutex,NULL); // 互斥锁初始化
    pthread_cond_init(&cd, NULL); // 条件变量初始化
    init();
    for(int i=0;i<m;i++) {
        pthread_create(&td[i],NULL,thyid,(void*)i); // 创建线程
    }
    for(int i=0;i<m;i++) {
        pthread_join(td[i],NULL); // 调用时阻塞当前线程直到返回
    }
    cout<<endl<<" *********************** "<<endl<<endl;
    cout<<"至此,所有线程执行完毕!!!"<<endl;
    return 0;
}

在这里插入图片描述

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值