对,我又没事干,拿C++11写了个银行家算法的模拟程序。

使用了:OpenCV4.1 库来做显示(MFC太旧了,QT环境给我搞炸了。。。懒得弄了,选择OpenCV,虽然这个库是用来做机器视觉的。。。莫怪)

首先我们定义一个模拟系统类

创建m个资源,n个线程(Thread级),假装下是进程级的(要上底层实现进程调度)。

检测可行解的算法,我使用了DFS,时间复杂度是。。。O(m^2+n^2)....剪了两次枝,感觉要是m,n太大的话还是会很慢。有时间可以试试看,用启发式优化下,然后将可达性转换一下试试看。

下面附代码:

【banker.h】

/*一个银行家算法类使用了C++11标准,OpenCV4.1库作者:吕翔宇E-mail:630056108@qq.com2019年5月27日版权所有!ALL RIGHTS RESERVED!
*/
#pragma once#pragma warning(disable:4996)#define DEBUG#include<ctime>
#include<cstring>#include<iostream>
#include<vector>
#include<string>
#include<queue>#include<opencv2/opencv.hpp>#include<mutex>
#include<thread>
#include<condition_variable>class banker{
public:banker();~banker();private:int resourceNum;                      // 资源种类数量int *resourceAvailable;                    // 各种资源的最大量int **resourceNeed;                      // 需求矩阵int **resourceHave;                      // 现在占有的资源int *request;                         // 资源请求向量int threadNum;                         // 线程数量std::vector<std::thread> threads;      // 线程列表std::vector<cv::Scalar> threadColor;   // 线程所代表的颜色int *status;                         // 进程状态,1-就绪态,2-运行态,3-阻塞态 -1终止状态public:void drawResource();                   // 绘制需求列表启动函数void drawThread();                     // 绘制线程列表启动函数private:std::vector<cv::Scalar> resourceColor;   // 资源所代表的颜色void _drawResource();                    // 绘制需求列表void _drawThread();                        // 绘制线程列表启动函数bool allocate(int, int, int);          // 资源随机分配语句bool check();                            // 银行家检测算法std::mutex cpuLock;private:cv::Mat theadWindow;private:void threadFunction(int );             // 进程函数void printNeed();                        // 打印需求表private:bool dfs(int, std::vector<int> &);        // 深搜寻找可行解};

【banker.cpp】

/*一个银行家算法类使用了C++11标准,OpenCV4.1库作者:吕翔宇E-mail:630056108@qq.com2019年5月27日版权所有!ALL RIGHTS RESERVED!
*/
#include "banker.h"banker::banker(){theadWindow = cv::Mat::zeros(cv::Size(450, 800), CV_8SC3);srand(time(NULL));resourceNum = rand()%10+4; //生产随机资源数resourceAvailable = new int[resourceNum];std::cout << "资源数:" << resourceNum << std::endl;//为每个资源分配一个颜色,并随机分配资源数for (int i = 0; i < resourceNum; i++) {resourceColor.push_back(cv::Scalar(rand()%255, rand() % 255, rand() % 255));resourceAvailable[i] = rand() % 10 + 1;}//drawResource();// 为每一个进程随机分配一个合理的需求资源threadNum = rand() % 10 + 4;    //生产线程数resourceNeed = new int*[threadNum];resourceHave = new int*[threadNum];status = new int[threadNum];for (int i = 0; i < threadNum; i++) {status[i] = 1;}for (int i = 0; i < threadNum; i++) {resourceNeed[i] = new int[resourceNum];resourceHave[i] = new int[resourceNum];threadColor.push_back(cv::Scalar(rand() % 255, rand() % 255, rand() % 255));for (int j = 0; j < resourceNum; j++) {resourceNeed[i][j] = rand() % (resourceAvailable[j]+1);    // 需求不能大于总量resourceHave[i][j] = 0;}}for (int i = 0; i < threadNum; i++) {threads.push_back(std::thread(&banker::threadFunction, this, i));}_sleep(400); // 没有使用mutex将控制台读写做成互斥的,这里sleep下// 初始化画threadcv::putText(theadWindow, "lable", cv::Point(10, 10), cv::FONT_HERSHEY_COMPLEX, 0.5, cv::Scalar(255, 255, 255));cv::putText(theadWindow, "status", cv::Point(200, 10), cv::FONT_HERSHEY_COMPLEX, 0.5, cv::Scalar(255, 255, 255));cv::putText(theadWindow, "color", cv::Point(400, 10), cv::FONT_HERSHEY_COMPLEX, 0.5, cv::Scalar(255, 255, 255));int step = 800.0 / threadNum;int loc = 50;   // 行像素for (int i = 0; i < threadNum; i++, loc += step) {cv::putText(theadWindow, std::to_string(i), cv::Point(10, loc), cv::FONT_HERSHEY_COMPLEX, 0.5, cv::Scalar(255, 255, 255));//cv::putText(window, std::to_string(resourceAvailable[i]), cv::Point(200, loc), cv::FONT_HERSHEY_COMPLEX, 0.5, cv::Scalar(255, 255, 255));cv::Point pts[1][5];pts[0][0] = cv::Point(400, loc);pts[0][1] = cv::Point(400, loc + 20);pts[0][2] = cv::Point(420, loc + 20);pts[0][3] = cv::Point(420, loc);pts[0][4] = cv::Point(400, loc);const cv::Point * ppts[] = { pts[0] };int npt[] = { 5 };cv::fillPoly(theadWindow, ppts, npt, 1, threadColor[i], 8);}printNeed();drawThread();
}
banker::~banker()
{for (int i = 0; i < threadNum; i++)threads[i].detach();delete resourceAvailable;
}
void banker::drawResource() {new std::thread(&banker::_drawResource,this);
}
void banker::_drawResource() {//std::cout << "开始绘制资源列表:" << std::endl;//cv::destroyWindow("资源表");cv::namedWindow("资源表");cv::Mat window = cv::Mat::zeros(cv::Size(450,820),CV_8SC3);cv::putText(window, "lable",cv::Point(10,10), cv::FONT_HERSHEY_COMPLEX,0.5,cv::Scalar(255,255,255));cv::putText(window, "avaliable", cv::Point(200, 10), cv::FONT_HERSHEY_COMPLEX, 0.5, cv::Scalar(255, 255, 255));cv::putText(window, "color", cv::Point(400, 10), cv::FONT_HERSHEY_COMPLEX, 0.5, cv::Scalar(255, 255, 255));int step = 800.0 / resourceNum;int loc = 50; // 行像素for (int i = 0; i < resourceNum; i++,loc+=step) {cv::putText(window, std::to_string(i), cv::Point(10, loc), cv::FONT_HERSHEY_COMPLEX, 0.5, cv::Scalar(255, 255, 255));cv::putText(window, std::to_string(resourceAvailable[i]     ), cv::Point(200, loc), cv::FONT_HERSHEY_COMPLEX, 0.5, cv::Scalar(255, 255, 255));cv::Point pts[1][5];pts[0][0] = cv::Point(400, loc);pts[0][1] = cv::Point(400, loc + 20);pts[0][2] = cv::Point(420, loc + 20);pts[0][3] = cv::Point(420, loc);pts[0][4] = cv::Point(400, loc);const cv::Point * ppts[] = { pts[0] };int npt[] = { 5 };cv::fillPoly(window, ppts, npt, 1, resourceColor[i], 8);}cv::imshow("资源表", window);cv::waitKey(0);
}void banker::printNeed() {std::cout << "---------------------需求表-----------------------\n";std::cout << "编号\t";for (int i = 0; i < resourceNum; i++) {std::cout << "R" << i<<"\t";}std::cout << std::endl;for (int i = 0; i < threadNum; i++) {if(status[i]!=-1)std::cout << "[" << i << "]\t"; elsestd::cout << "[*" << i << "]\t";for (int j = 0; j < resourceNum; j++) {std::cout << resourceNeed[i][j] << "\t";}std::cout << std::endl;}std::cout << "--------------------------------------------------\n";
}
void banker::drawThread() {new std::thread(&banker::_drawThread, this);
}
void banker::_drawThread() {cv::imshow("线程表", theadWindow);cv::waitKey(0);
}void banker::threadFunction(int id) {std::cout << "[" << id << "]创建了一个进程\t" << std::this_thread::get_id() << std::endl;int step = 800.0 / threadNum;bool finish = false;int needId = -1;int needNum = -1;while (true) {if (finish) break;cpuLock.lock();status[id] = 2;std::cout << id << " 获取了cpu执行权\n";// 需求为空时,随机挑选一个资源请求分配if (true) {//将true改成needId == -1,可以每次都生产一个新的需求int offset = rand() % resourceNum;for (int i = offset; i < resourceNum; i++) {// 随机挑一个if (resourceNeed[id][i % resourceNum] > 0) {needId = i % resourceNum;needNum = (rand() % resourceNeed[id][i % resourceNum]) + 1;break;}}}// 尝试分配 if(needId!=-1&& allocate(id, needId, needNum)){// 分配成功}else{status[id] = 3;// 这里有问题,这里实现成了就绪态。。。C++11还不太精通。。。cpuLock.unlock();_sleep(100);continue;}// 绘制图像cv::putText(theadWindow, "runing", cv::Point(200, step*id + 50), cv::FONT_HERSHEY_COMPLEX, 0.5, cv::Scalar(0, 255, 0));drawThread();
// 等待时间_sleep(100);//清除绘制的内容cv::Point pts[1][5];pts[0][0] = cv::Point(200, step*id + 40);pts[0][1] = cv::Point(200, step*id + 40 + 20);pts[0][2] = cv::Point(280, step*id + 40 + 20);pts[0][3] = cv::Point(280, step*id + 40);pts[0][4] = cv::Point(280, step*id + 40);const cv::Point * ppts[] = { pts[0] };int npt[] = { 5 };cv::fillPoly(theadWindow, ppts, npt, 1, cv::Scalar(0, 0, 0), 8);cpuLock.unlock();// 检测是否可以退出bool nag = true;for (int i = 0; i < resourceNum; i++) {if (resourceNeed[id][i] > 0) {nag = false;break;}}if (nag) {break;}needId = -1;needNum = -1;status[id] = 1;_sleep(100);}status[id] = -1;cpuLock.lock();cv::putText(theadWindow, "terminated", cv::Point(200, step*id + 50), cv::FONT_HERSHEY_COMPLEX, 0.5, cv::Scalar(0, 0, 255));cpuLock.unlock();std::cout << "[" << id << "我退出了\t" << std::this_thread::get_id() << std::endl;// 归还资源for (int i = 0; i < resourceNum; i++) {resourceAvailable[i] += resourceHave[id][i];resourceHave[id][i] = 0;}drawResource();// 当所有进程退出时结束模拟bool nag = true;for (int i = 0; i < threadNum; i++) {if (status[i] != -1) {nag = false;break;}}if (nag) {std::cout << "按任意按键退出";drawThread();}
}bool banker::allocate(int id,int resourceId, int needNum) {// 资源不足if (resourceId == -1) {system("pause");}if (resourceAvailable[resourceId] < needNum) {std::cout << " 向 " << id << " 分配 " << resourceId << "号资源 " << needNum << "个[资源不足 拒绝]\n ";return false;}std::cout << " 尝试向 " << id << " 分配 " << resourceId << "号资源 " << needNum << "个 ";resourceAvailable[resourceId] -= needNum;resourceNeed[id][resourceId] -= needNum;resourceHave[id][resourceId] += needNum;if (check()) {std::cout << " [授予]\n";
#ifdef DEBUGdrawResource();printNeed();
#endif // DEBUG// 检测通过return true;}else {// 检测不通过std::cout << " [不安全 拒绝]\n";resourceAvailable[resourceId] += needNum;resourceNeed[id][resourceId] += needNum;resourceHave[id][resourceId] -= needNum;return false;}
}bool banker::check() {bool rnt = false;std::vector<int> q;          // 可行解队列int checkLeft = threadNum;for (int i = 0; i < threadNum; i++) {if (status[i] == -1) {//q.push_back(i);checkLeft--;}}return dfs(checkLeft, q);
}
bool banker::dfs(int checkLeft, std::vector<int> &q) {if (checkLeft == 0) { std::cout << "\n可行解:";for (int i = 0; i < q.size(); i++)std::cout << q[i] << " ";std::cout << std::endl;return true; }// 选取一个未选择的进程,检测它是否可以运行完for (int i = 0; i < threadNum; i++) {// 排除已检测过的进程bool nag = true;if (status[i] == -1)continue;// 排除已经终止了的线程for (int j = 0; j < q.size(); j++) {if (i == q[j])nag=false;}if (!nag) continue;// 分配所有需要的资源nag = true;for (int j = 0; j < resourceNum; j++) {if (resourceAvailable[j] < resourceNeed[i][j]) {nag = false;break;}}if (!nag) continue;// 资源不足无法分配// 假设分配了,并等待它运行结束归还了所有资源,计算下一个可行的进程for (int j = 0; j < resourceNum; j++) {resourceAvailable[j] += resourceHave[i][j];}q.push_back(i);// 如果返回的是可行的,则直接全部返回if (dfs(checkLeft - 1, q)) {// 恢复状态for (int j = 0; j < resourceNum; j++) {resourceAvailable[j] -= resourceHave[i][j];}return true;}// 恢复状态for (int j = 0; j < resourceNum; j++) {resourceAvailable[j] -= resourceHave[i][j];}q.pop_back();}return false;
}

【main.cpp】

#include<iostream>
#include<cstdlib>
#include<opencv2/opencv.hpp>#include"banker.h"int main() {banker banker;system("pause");
}

动图效果:

反正只要配置对了,这个程序是绝对没问题的!

C++11 操作系统实验——银行家算法相关推荐

  1. 计算机操作系统实验银行家算法,实验六 银行家算法(下)

    实验六 银行家算法(下) 一.实验说明 实验说明:本次实验主要是对银行家算法进行进一步的实践学习,掌握银行家算法的整体流程,理解程序测试时每一步的当前状态,能对当前的资源分配进行预判断. 二.实验要求 ...

  2. 操作系统实验——银行家算法

    文章目录 一.实验目的 二.实验内容和要求 三.实验原理 算法实现 四.实验程序 代码如下: 五.验证数据和运行结果 运行结果截图 六.思考与分析 附 一.实验目的 掌握银行家算法思想,并能编程实现. ...

  3. 操作系统之银行家算法—详解流程及案例数据

    操作系统之进程调度--优先权法和轮转法(附上样例讲解) 操作系统之银行家算法-详解流程及案例数据 操作系统之多线程编程-读者优先/写者优先详解 操作系统之存储管理--FIFO算法和LRU算法 操作系统 ...

  4. 操作系统之银行家算法解析

    操作系统之银行家算法解析(带例题) 利用银行家算法避免死锁,首先我们先来明晰一下银行家算法的数据结构,其中必须设置四个数据结构,Available,Max,Allocation,Need. Avail ...

  5. 操作系统 进程调度-银行家算法实验报告

    实验要求 一. 实验目的 死锁会引起计算机工作僵死,因此操作系统中必须防止.本实验的目的在于让学生独立的使用高级语言编写和调试一个系统动态分配资源的简单模拟程序,了解死锁产生的条件和原因,并采用银行家 ...

  6. 【计算机操作系统】银行家算法的模拟实现

    文章目录 前言 1 实验相关知识理论 1.1 死锁的概念 1.2 产生死锁的原因 1.3 避免死锁的方法 1.4 解除死锁的方法 2 实验设计思路 3 实验设计涉及到的数据结构 4 程序算法设计 4. ...

  7. 操作系统-资源分配银行家算法

    资源分配----银行家算法 一. 实验目的 模拟实现银行家算法,用银行家算法实现资源分配和安全性检查.通过本次实验,使学生加深对死锁概念的理解和掌握,并培养学生对操作系统课程的兴趣与高级语言设计的能力 ...

  8. 操作系统知识——银行家算法

    用自己理解的语言描述,如有错误,请疯狂打脸没关系,希望能够指出来. 0. 主要思想 分配资源之前,判断系统是否安全. 银行家算法是一种资源分配和避免死锁的算法,它通过模拟所有资源的分配方式来测试安全性 ...

  9. 银行家算法c语言博客,操作系统之银行家算法

    银行家算法是一种在多道程序系统中避免多个进程并发执行所带来的死锁问题.所谓死锁(Deadlock),是指多个进程在运行过程中因争夺资源而造成的一种僵局(DeadlyEmbrace),当进程处于这种状态 ...

最新文章

  1. CSS3颜色不透明度如何设置
  2. 【中级软考】什么是实时操作系统?(RTOS:Real Time Operating System)
  3. vba fso读utf 文本_利用FSO对象操作文件
  4. GDCM:处理(各种操作处理)DICOM图像文件的测试程序
  5. OpenCV:简单计算曲线弧度-弓形弧度
  6. 计算机安全基础:认证技术知识笔记
  7. 关于春招 秋招面试的一些经验
  8. python怎么做软件界面_python – 如何自定义桌面应用程序的标题栏和窗口
  9. hl3150cdn打印不了照片_如何在美国打印证件照片 (Passport Photos)?
  10. 更新linux gcc版本到gcc 4.4.2
  11. 笔记本测试屏幕的型号的软件,哪个软件可以检测到笔记本的型号
  12. php怎么用origin打开,[转载]origin 使用技巧 (4)
  13. Java-String类学习笔记
  14. 网络协议和标准——IEEE802
  15. 安装.net补丁后mscorsvw.exe占CPU100%的问题
  16. Harmony鸿蒙开发 四、Ability的生命周期
  17. 正则表达式-2021
  18. 技能兴鲁试题--可视化
  19. 【C++】1014 福尔摩斯的约会
  20. python编程水上行走_普通人如何水上行走,只要速度足够的快,何愁不能水上漂...

热门文章

  1. 初学python:Python 3的下载、安装、第一个程序(Helloworld.py)与卸载
  2. 若依前后端分离框架学习-6:日志管理
  3. Windows中安装配置Maven详细教程
  4. 苏州大学21年计算机考研情况 复试python上机,专硕一志愿平均分376.9分
  5. [office]word2010、word2013、word2016比较查重软件
  6. 使用OpenCV和Python标记超像素色彩
  7. 等保中级测评师复习.07
  8. MTK,4G全网通模块设计资料
  9. 软考软件设计师考试经验与体会
  10. ubuntu安装mysql详细过程