C语言实现 操作系统 银行家算法
/****************************************************
银行家算法
算法思想:
1. 在多个进程中,挑选资源需求最小的进程Pmin。
可能存在多类资源,这时暂取第一类资源作为基准 2. 验证剩余的资源是否能满足进程Pmin各类资源的最大资源需求,
若满足。意味着进程可以执行完毕。最后释放占有着的资源。此时回收Pmin占有的资源,
将此进程标志为FINISH,并唤醒那些等待的进程(实际就是改变等待进程的状态标志)
若不满足,表明资源不够,将此进程标志为WAIT 3. 循环整个过程,当检測到进程所有为FINISH时,表明是安全状态
检測到所有的进程为WAIT时。表明可能死锁了,是一个非安全状态 林育彬 2014/10/17
*****************************************************/ #include <stdio.h>
#include <malloc.h>
#include <string.h> // 安全状态标志
#define TRUE 0
#define FALSE -1 // 进程状态标志
#define FINISH 1
#define READY 0
#define WAIT -1 // 为了在函数调用的时候,降低參数的个数,这里将声明一些变量为全局变量
int *Available = NULL; // 剩余资源可用数量
int *Max = NULL; // 每一个进程最大的需求量
int *Allocation = NULL; // 每一个进程已经分配的资源数
int *Need = NULL; // 每一个进程还须要的资源数
int *SafeList = NULL; // 存储一个安全序列 int initData(const int pCount, const int rCount)
{
int i = 0; Available = (int*)malloc(rCount * sizeof(int));
Max = (int*)malloc(rCount*pCount * sizeof(int));
Allocation = (int*)malloc(rCount*pCount * sizeof(int));
Need = (int*)malloc(rCount*pCount * sizeof(int));
SafeList = (int*)malloc((pCount+1) * sizeof(int)); // SafeList[0] 作为一个安全标志位 if (Available == NULL || Max == NULL || Allocation == NULL
|| Need == NULL || SafeList == NULL)
{
printf("out of space\n");
return FALSE;
} SafeList[0] = 0; // 初始化,表明不存在安全序列 // 最大需求量
for(i=0; i<rCount*pCount; ++i)
{
scanf("%d", &Max[i]);
} // 已分配资源数量
for(i=0; i<rCount*pCount; ++i)
{
scanf("%d", &Allocation[i]);
} // 剩余资源量
for(i=0; i<rCount; ++i)
{
scanf("%d", &Available[i]);
} // 计算需求数
for(i=0; i<rCount*pCount; ++i)
{
Need[i] = Max[i] - Allocation[i];
} return TRUE;
} // 測试此时的进程状态
int testStatus(const int pCount, const int rCount)
{
int pMin = 0; // 最小需求进程ID
int pWait = 0; // 等待进程数
int pFinish = 0; // 完毕进程数
int p = 0;
int r = 0;
int posList = 1; // 安全序列下标 int *pStatus = (int*)malloc(pCount * sizeof(int)); // 进程的标志状态
int *pAvai_cpy = (int*)malloc(rCount * sizeof(int)); // Available 的一份拷贝。避免破坏数据
int *safeList_tmp = (int*)malloc((pCount+1) * sizeof(int)); if (pStatus == NULL || pAvai_cpy == NULL || safeList_tmp == NULL)
{
printf("out of space\n");
return FALSE;
} // 初始化所有的进程为就绪状态
memset(pStatus, READY, pCount * sizeof(int));
// 拷贝 Available
memcpy(pAvai_cpy, Available, rCount * sizeof(int)); while(pFinish != pCount && pWait != pCount)
{ // 以第一类资源为基准,挑选资源需求最小的进程
int needMin = -1;
pMin = 0;
for (p=0; p<pCount; ++p)
{
if (pStatus[p] != READY)
continue; if (needMin == -1 || Need[p*rCount + 0] < needMin) // 第一类需求资源, needMin == -1 初次取值
{
needMin = Need[p*rCount + 0];
pMin = p; }
} // 验证剩余资源是否能满足最小资源进程的需求
for (r=0; r<rCount; ++r)
{
if (Need[pMin*rCount + r]> pAvai_cpy[r])
{
// 满足不了
break;
}
} if (r == rCount)
{
// 添加到安全序列中
safeList_tmp[posList++] = pMin+1; // 满足各类资源需求
pStatus[pMin] = FINISH;
pFinish++; // 回收资源
for (r=0; r<rCount; ++r)
{
pAvai_cpy[r] += Allocation[pMin*rCount + r];
} // 唤醒等待的进程
for (p=0; p<pCount; ++p)
{
if (pStatus[p] == WAIT)
{
pStatus[p] = READY;
pWait--;
}
}
}
else
{
// 表明无法满足,进程等待
pStatus[pMin] = WAIT;
pWait++;
}
} free(pStatus);
free(pAvai_cpy); // 验证状态
if (pFinish == pCount)
{
// 更新安全序列
safeList_tmp[0] = 1; // 安全标志位置1。表明存在安全序列
memcpy(SafeList, safeList_tmp, (pCount+1) * sizeof(int) );
free(safeList_tmp); return TRUE;
}
else
{
free(safeList_tmp);
return FALSE;
}
} void showSafeList(const int pCount)
{
if (SafeList != NULL)
{
int i = 0;
if (SafeList[i] != 1)
{
printf("不存在安全序列\n");
}
else
{
++i;
printf("安全序列:");
while(i <= pCount)
{
printf("p%d ", SafeList[i++]);
}
printf("\n");
}
}
else
{
printf("不存在安全序列\n");
} } // 測试资源请求,假设满足,则分配,不满足,则不分配资源 modify 2014/11/2
int request(const int pId, const int pCount, const int rCount, const int *reqList)
{
int *Avai_cpy = (int*)malloc(rCount * sizeof(int));
int *pId_Allo = (int*)malloc(rCount * sizeof(int)); // 保存当前进程的一条分配情况,
int *pId_Need = (int*)malloc(rCount * sizeof(int)); // 保存当前进程的一条需求情况 int r = 0;
const int locate = pId*rCount; // 定位到进程的位置 if (Avai_cpy == NULL || pId_Allo == NULL || pId_Need == NULL)
{
printf("out of space\n");
return FALSE;
} // 做数据备份
for(r=0; r<rCount; ++r)
{
pId_Allo[r] = Allocation[locate + r];
pId_Need[r] = Need[locate + r];
Avai_cpy[r] = Available[r];
} // 资源分配
for (r=0; r<rCount; ++r)
{
if (reqList[r] > Available[r])
{
return FALSE;
} Allocation[locate + r] += reqList[r];
Available[r] -= reqList[r];
Need[locate + r] -= reqList[r];
} // test
if (testStatus(pCount, rCount) != TRUE)
{
// 分配之后处于非安全状态,数据还原
for(r=0; r<rCount; ++r)
{
Allocation[locate + r] = pId_Allo[r];
Need[locate + r] = pId_Need[r];
Available[r] = Avai_cpy[r];
} free(Avai_cpy);
free(pId_Allo);
free(pId_Need);
Avai_cpy = pId_Allo = pId_Need = NULL; return FALSE;
}
else
{
// 成功分配 free(Avai_cpy);
free(pId_Allo);
free(pId_Need);
Avai_cpy = pId_Allo = pId_Need = NULL; return TRUE;
} return TRUE;
} // 清理空间
void destory()
{
if (Available != NULL)
{
free(Available);
} if (Max != NULL)
{
free(Max);
} if (Allocation != NULL)
{
free(Allocation);
} if (Need != NULL)
{
free(Need);
} if (SafeList != NULL)
{
free(SafeList);
} Available = NULL;
Max = NULL;
Allocation = NULL;
Need = NULL;
SafeList = NULL; //printf("destory\n"); } int main()
{
int rCount = 0;
int pCount = 0; // request
int pId = 2;
int reqList[] = {0, 3, 4}; freopen("data.txt", "r", stdin); // 为了測试的方便。这里使用重定位 // read data
scanf("%d %d", &pCount, &rCount);
initData(pCount, rCount); // test status
if (testStatus(pCount, rCount) == TRUE)
{
printf("是安全状态\n");
}
else
{
printf("非安全状态\n");
} showSafeList(pCount); //请求资源 p2 请求资源 0 3 4
if (request(pId, pCount, rCount, reqList) == TRUE)
{
printf("资源成功分配\n");
}
else
{
printf("该请求无法满足安全状态\n");
} destory(); return 0;
} /********************************************
data.txt
5 3 5 5 9
5 3 6
4 0 11
4 2 5
4 2 4 2 1 2
4 0 2
4 0 5
2 0 4
3 1 4 2 3 3
********************************************/
C语言实现 操作系统 银行家算法的更多相关文章
- 操作系统——银行家算法(Banker's Algorithm)
之前写过一篇关于死锁和银行家算法的详细描述的博客https://www.cnblogs.com/wkfvawl/p/11598647.html 写这篇博客的目的,主要是详细讲解一下银行家算法以及代码的 ...
- 【操作系统】银行家算法实现(C语言)
[操作系统]银行家算法实现(C语言) 注意:本人编码水平很菜.算是自己的一个总结.可能会有我还没有发现的bug.如果有人发现后可以指出,不胜感激. 1.银行家算法: 我们可以把操作系统看作是银行家,操 ...
- 操作系统,银行家算法模拟实现(Windows 环境 C++)
计算机操作系统课设需要,写了两个下午的银行家算法(陷在bug里出不来耽误了很多时间),参考计算机操作系统(汤子瀛) 实现过程中不涉及难度较大的算法,仅根据银行家算法的思想和步骤进行实现.以下为详细步骤 ...
- python模拟银行家算法
前言: 大二第一学期学习了操作系统,期末实验课题要求模拟算法.遂根据自己学习的python写下此文.以此锻炼自己编码能力.虽说是重复造轮子,但还是自己的思路体现 代码及注释如下(银行家算法不再赘述): ...
- 预防和避免死锁的方法及银行家算法的java简单实现
预防死锁 (1) 摒弃"请求和保持"条件 基本思想:规定所有进程在开始运行之前,要么获得所需的所有资源,要么一个都不分配给它,直到所需资源全部满足才一次性分配给它. 优点:简单.易 ...
- C程序模拟实现银行家算法
C程序模拟实现银行家算法 上周又做操作系统实验,题目是用程序模拟实现银行家算法,写了半天还真有点晕,主要是因为想尽可能符合课本上的描述,所以写出来的程序就比较恶心了,好了,银行家算法就不多说了,不了解 ...
- 银行家算法之JavaScript实现
上学期有个课程叫做操作系统,期末的时候这课程还有个课程设计,其中有个题目叫做银行家算法. 什么是银行家算法我就不解释了! 看着同学们的设计,大同小异甚至前篇一律. 清一色的控制台程序,清一色的蛋疼输入 ...
- java面试题之死锁产生的条件,以及如何避免死锁,银行家算法,产生死锁后如何解决(阿里面试题)
死锁产生的四个必要条件: 互斥:一个资源每次只能被一个进程使用(资源独立) 请求与保持:一个进程因请求资源而阻塞时,对已获得的资源保持不放(不释放锁) 不剥夺:进程已获得的资源,在未使用之前,不能强行 ...
- C# Math.Round()的银行家算法
可能很多人都跟我一样,都只知道Math.Round()是C#中用来做四舍五入,保留指定小数位的 但实际上它并不是真正的四舍五入,而是银行家算法的四舍六入五取偶 事实上这也是IEEE的规范,因此所有符合 ...
随机推荐
- iOS应用崩溃日志揭秘2
这篇文章还可以在这里找到 英语 场景 4: 吃棒棒糖时闪退! 用户邮件说, “当rage master吃棒棒糖时应用就闪退…” 另一用户说, “我让rage master 吃棒棒糖,没几次应用就闪退了 ...
- Rebound动画框架简单介绍
Rebound动画框架简单介绍 Android菜鸟一枚,有不对的地方希望大家指出,谢谢. 最近在接手了一个老项目,发现里面动画框架用的是facebook中的Rebound框架,由于以前没听说过,放假时 ...
- dede实战系统:更换成kindEditor编辑器
最近由于项目需要,在搞dedeCMS,发现dede自带的ckEditor在word粘贴这方面做得不是很好,从word上面直接ctrl+V的内容跟wrod上面的表现样式相差很大,客户很不爽(因为是编辑的 ...
- 研读:Shielding applications from an untrusted cloud with Haven
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvdHJ1c3Ribw==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA ...
- 【好】Paxos以及分布式一致性的学习
Paxos,一言以蔽之,我们需要一种提交协议来确保分布式系统中的全局操作即使是在发生故障的情况下也能保证正确性. 跟拜占庭将军问题是不同的问题,虽然拜占庭也是Lamport提出的.拜占庭里面有叛徒,有 ...
- vue2.0 仿手机新闻站(一)项目开发流程
vue仿手机新闻站: 1.拿到静态页面,直接用vue边布局,边写 2.假数据 没有用任何UI组件,切图完成 做项目基本流程: 1.规划组件结构 Nav.vue Header.vue Home.vue ...
- [Sqlite]-->嵌入式数据库事务理解以及实例操作
引子: 1. Sqlite在Windows.Linux 和 Mac OS X 上的安装过程 2,嵌入式数据库的安装.建库.建表.更新表结构以及数据导入导出等等具体过程记录 SQLite 事务(Tran ...
- apue学习笔记(第九章 进程关系)
本章将详细地说明进程组以及POSIX.1引入的会话的概念.还将介绍登录shell和所有从登录shell启动的进程之间的关系 终端登录 BSD终端登录.系统管理者创建通常名为/etc/ttys的文件,其 ...
- 面向对象在JavaScript中的接口实现
接口是面向对象编程的基础.它是一组包括了函数型方法的数据结构,与类一样.都是编程语言中比較抽象的概念.比方生活中的接口.机顶盒.人们利用它来实现收看不同频道和信号的节目,它宛如对不同类型的信息进行集合 ...
- 在Mac上ppt导出pdf
Step1:打开要操作的ppt,然后Command+P(print),出来打印的界面 Step2:在左下端选择Save as PDF就可以