#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;
}
操作系统:Banker’s Algorithm
最新推荐文章于 2023-01-02 10:49:15 发布