中国计量学院操作系统课程设计银行家算法+哲学家进餐讲课讲稿Word格式文档下载.docx
《中国计量学院操作系统课程设计银行家算法+哲学家进餐讲课讲稿Word格式文档下载.docx》由会员分享,可在线阅读,更多相关《中国计量学院操作系统课程设计银行家算法+哲学家进餐讲课讲稿Word格式文档下载.docx(23页珍藏版)》请在冰豆网上搜索。
=NEED[I,N],则转
(2);
(2)如果Request[N]<
=AVAILABLE,则转(3);
(3)系统试探分配资源,修改相关数据:
NEED=NEED-REQUEST
(4)系统执行安全性检查,如安全,则分配成立;
否则试探险性分配作废,系统恢复原状,进程等待。
3.数据结构
intneed[10][3];
//
intmax[10][3];
//最大需求
intallocation[10][3];
//已分配
intavailable_temp[3];
//可用,临时变量,用户尝试性分配request资源
intavailable[3];
//可用
intpath[10];
//记录安全序列
intis_save;
//是否产生安全序列标示符
4.主函数说明
//初始化need,max,allocation,available,及判断初始状态是否有安全序列
voidinit();
voidshowMenu();
//打印出菜单
voidprint_sav_seq();
//打印安全序列及分配过程
voiddfs(intidx);
//改程序核心函数,用深度优先搜索查找安全序列
voidbanker();
//银行家算法入口
voidramdon();
//随机分配算法入口
intmain();
//主程序入口
5.算法流程图
(主函数)
(银行家算法)
(随机分配算法)
三、调试记录与分析
初始化数据参照课本P110:
第一行为有3中资源,5个进程。
最后一行为各类资源可用情况。
中间数据位max,allocation,need:
35
753010743
322200122
902302600
222211011
433002431
332
即:
在下面这种状态中
MaxAllocationNeed
ABCABCABC
753010743
902302600
222211011
433002431
AvailableA:
3B:
3C:
2
请输入进程号和A,B,C请求的个数:
如果输入3000
Available变成A:
5B:
11C:
4
分析:
程序缺少对available更新条件的判断,因为available只在进程刚好完全执行完全后进行更新,即加上之前的Allocation。
所以,更改程序,如下
for(i=1;
i<
=3;
++i)
{
if(finished[i])continue;
if(process[i].nd.a==0&
&
process[i].nd.b==0&
process[i].nd.c==0)
{//即在进程刚好执行完成时进行process的更新
--cntProcess;
finished[i]=1;
available.a+=process[pr].alloc.a;
available.b+=process[pr].alloc.b;
available.c+=process[pr].alloc.c;
}
}
四、运行结果及说明
1.打印菜单
2.初始化数据,有安全序列则打印之并给出分配方案,
否则,需要用户提供正常的初始化数据再运行程序:
3.选择银行家算法,输入进程号,请求资源数
1)分配后仍有安全序列:
2)条件不符合,不能分配
3)资源分配后照成死锁,则取消分配
4.如果输入2,进入随机算法。
与3.2相同,给p0分配332。
使用随机分配算法仍然可以分配资源,如下图
但照成死锁。
而银行家算法由于检测到会产生死锁故不将分配资源给p0,如上图
没造成死锁,则给出安全序列,及分配后可以实行的分配方案
五、课程设计总结。
总体来说,这个课程设计是5个当中较简单的,只要了解银行家算法,及随机分配算法,然后穷举所有情况。
就可以做出相应的判断:
是否会进入不安全状态
需要注意的是,对于银行家算法,如果某进程提出了不合理请求后,要是判断后会进入不安全状态,需要将资源还原。
通过这次课程设计实践,不仅让我对银行家算法的实现有了更深刻的理解,也让我觉得自己的动手能力有了很大的提高;
自信心也增强了,在课程设计中自己动脑子解决遇到的问题,书本上的知识有了用武之地,这巩固和深化了自己的知识结构.
通过这次的理论与实践相结合,我相信,只要自己在每一次实践中都能仔细思考,课程设计其实都不会很难,关键在于自己能不能认真思考,能不能亲自动手做实验,而不是想着其他人的劳动果实,
附录:
(源代码)
#include<
stdio.h>
stdlib.h>
string.h>
//还需
//可用
intm,n;
//资源种类m种,进程数n
//记录安全序列
//是否产生安全序列
intmark[10];
//记录某进程是否已分配资源
FILE*file;
voidinit(){
printf("
从init.date初始化程序\n"
);
file=fopen("
init.dat"
"
r"
fscanf(file,"
%d%d"
&
m,&
n);
for(inti=0;
i<
n;
i++){
for(intj=0;
j<
m;
j++){//max
fscanf(file,"
%d"
&
max[i][j]);
}
j++){//allocation
allocation[i][j]);
j++){//need
need[i][j]);
}
for(intj=0;
j++){//available_temp
fscanf(file,"
available_temp[j]);
available[j]=available_temp[j];
memset(mark,0,sizeof(mark));
is_save=0;
pressEntertocontinue..."
getchar();
dfs(0);
}
voidshowMenu(){
puts("
\n*****************************************************"
*0.初始化数据1.银行家算法2.随机分配算法3.退出*"
*******************************************************"
voidprint_sav_seq(){
安全序列如下:
"
j++){
printf(j?
"
-->
:
printf("
p%d"
path[j]);
*****************************************************************"
*WorkNeedAllocationWork+AllocationFinish*"
*ABCABCABCABC*"
available_temp[j]=available[j];
inti=path[j];
*P%d"
i);
%3d%3d%3d"
available_temp[0],available_temp[1],available_temp[2]);
need[i][0],need[i][1],need[i][2]);
allocation[i][0],allocation[i][1],allocation[i][2]);
available_temp[0]+=allocation[i][0];
available_temp[1]+=allocation[i][1];
available_temp[2]+=allocation[i][2];
%3d%3d%3dtrue*\n"
可用资源:
A->
%d;
B->
C->
%d\n\n\n"
available[0],available[1],available[2]);
voiddfs(intidx){
inti,j;
if(is_save){
return;
if(idx==n){
is_save=1;
for(i=n-1;
i>
=0;
i--){
//for(i=0;
if(mark[i]){//已分配,跳过
continue;
//判断各类资源是否够分配
for(j=0;
if(need[i][j]>
available_temp[j]){
break;
if(j==m){
//可以分配
mark[i]=1;
for(j=0;
available_temp[j]+=allocation[i][j];
path[idx]=i;
dfs(idx+1);
if(is_save){
return;
available_temp[j]-=allocation[i][j];
//还原
mark[i]=0;
voidbanker(){
intoper,i,j,flag1=0,flag2=0;
while(true){
flag1=flag2=0;
请输入要操作的进程号:
scanf("
i);
请输入各类资源的请求数:
intrequest[3];
%d%d%d"
request[0],&
request[1],&
request[2]);
if(request[j]>
need[i][j]){
flag1=1;
available[j]){
flag2=1;
if(flag1){
printf("
request%d(%d,%d,%d)<
=need%d(%d,%d,%d)不成立\n"
i,request[0],request[1],request[2],i,need[i][0],need[i][1],need[i][2]);
if(flag2){
=available(%d,%d,%d)不成立\n"
i,request[0],request[1],request[2],available[0],available[1],available[2]);
if(flag1==0&
flag2==0){
j++){//处理请求
allocation[i][j]+=request[j];
need[i][j]-=request[j];
available[j]-=request[j];
available_temp[j]=available[j];
memset(mark,0,sizeof(mark));
is_save=0;
dfs(0);
print_sav_seq();
}else{
for(j=0;
j++){//不能分配,还原之前修改项
available[j]+=request[j];
puts("
资源分配后会造成死锁,不能分配\n\n"
puts("
1.继续操作2.退出"
oper);
if(oper==2){
break;
voidramdon(){
请求资源已经分配,造成死锁\n\n"
intmain(){
showMenu();
请选择接下来的操作:
intoper;
switch(oper){
case0:
init();
if(is_save==1){
print_sav_seq();
}else{
puts("
无法找到安全序列,请先修改init.dat文件中的数据再运行程序"
return0;
case1:
banker();
case2:
ramdon();
case3:
return0;
default:
puts("
输入有误,清重试"
return0;
哲学家进餐死锁问题及避免算法的实现
课程设计内容与要求
复习Linux下进程和线程编程的内容,以及操作系统课本中关于五个哲学家进餐死锁问题原理,在Linux下利用线程和线程互斥锁的机制实现哲学家进餐问题,观察记录死锁现象。
并提出一种能解决五个哲学家进餐问题的一种方法,并编程实现之。
课程设计需要实现哲学家进餐问题发生死锁以及不发生死锁的两份程序。
1、主要函数
voidprintTime();
//打印时间
voideat(inti);
//第i个哲学家开始进餐
voidthink(inti);
//第i个哲学家开始思考
voidget(inti,intj);
//第j个哲学家拿起第i只筷子
voidput(inti,intj);
//第j个哲学家放下第i只筷子
void*f(void*arg);
//哲学家线程
//程序入口
2、流程图
(主函数)
(哲学家线程)
3.程序运行,数据分析
3分钟后:
附源代码:
time.h>
cstdio>
cstdlib>
pthread.h>
unistd.h>
staticpthread_mutex_tcs_mutex_ph[5]=PTHREAD_MUTEX_INITIALIZER;
//哲学家
staticpthread_mutex_tcs_mutex_ch[5]=PTHREAD_MUTEX_INITIALIZER;
//筷子
intchopstick[5]={0};
voidprintTime(){
inti;
time_ttimep;
time(&
timep);
chars[1024];
sprintf(s,"
当前时间%s:
ctime(&
timep));
for(i=23;
31;
s[i-23]=