




版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
PAGE19实训一、模拟进程操作原语实训目的:通过设计并调试创建、终止、阻塞、唤醒原语功能,有助于对操作系统中进程控制功能的理解,掌握操作系统模块的设计方法和工作原理。实训内容:设计创建、终止、阻塞、唤醒原语功能函数。设计主函数,采用菜单结构(参见后面给出的流程图)。设计“显示队列”函数,目的能将就绪、阻塞队列中的进程信息显示在屏幕上,以供随时查看各队列中进程的变化情况。实训步骤:1、系统总体结构:开始开始系统主菜单1…创建2…阻塞3…唤醒4…终止5…显示0…退出请输入您需要的功能(0-5):输入选择输入选择=?543210543210退出创建阻塞唤醒终止显示退出创建阻塞唤醒终止显示结束结束其中:进程名用P1,P2标识。优先级及运行时间:为实训题目二做准备。其中:进程名用P1,P2标识。优先级及运行时间:为实训题目二做准备。状态为:就绪、运行、阻塞,三种基本状态。指针:指向下一个PCB。进程名优先级运行时间状态指针实训代码:#include<stdio.h>#include<string.h>structPCB{ charname[4]; intpriority; intruntime;};voidmain(){ intx,t; inta=0; intk=0,r=1,i=0,j=0;//k为就绪队列总数,r堵塞队列总数 charname[4]; structPCBpcb[10]; structPCBpcb1[10];structPCBpcb2[10]; printf("菜单\n\n\n");printf("0退出系统\n");printf("1创建进程\n");printf("2堵塞进程\n"); printf("3唤醒进程\n"); printf("4终止进程\n"); printf("5显示进程\n");printf("\n"); strcpy(pcb1[0].name,"s");//堵塞队列 pcb1[0].priority=2; pcb1[0].runtime=3; while(1) { printf("请输入你的选择:"); scanf("%d",&x); if(x==0) break; if(x==1) { printf("创建进程\n"); printf("进程名:"); scanf("%s",&pcb[k].name); printf("优先级:"); scanf("%d",&pcb[k].priority); printf("运行时间:"); scanf("%d",&pcb[k].runtime); k=k+1; } if(x==2) { printf("堵塞进程\n"); printf("请输入要查找的进程:"); scanf("%s",name); for(j=0;j<=k;j++) { if(strcmp(pcb[j].name,name)==0) { t=j; strcpy(pcb2[a].name,pcb[t].name); pcb2[a].priority=pcb[t].priority; pcb2[a].runtime=pcb[t].runtime;strcpy(pcb1[r].name,pcb2[a].name); pcb1[r].priority=pcb2[a].priority; pcb1[r].runtime=pcb2[a].runtime; r=r+1; a=a+1; for(i=t;i<=k;i++) { strcpy(pcb[i].name,pcb[i+1].name); pcb[i].priority=pcb[i+1].priority; pcb[i].runtime=pcb[i+1].runtime; } k=k-1; printf("将就绪序列调度为运行:"); for(i=0;i<a;i++) printf("%s%d%d\n",pcb2[i].name,pcb2[i].priority,pcb2[i].runtime); printf("堵塞进程:\n"); for(j=0;j<r;j++) printf("%s%d%d\n",pcb1[j].name,pcb1[j].priority,pcb1[j].runtime); break; } else printf("该进程已是堵塞进程!\n"); break; } } if(x==3) { printf("唤醒进程\n"); printf("请输入要唤醒的进程:"); scanf("%s",name); for(i=0;i<r;i++) { if(strcmp(pcb1[i].name,name)==0) { t=i; strcpy(pcb[k].name,pcb1[t].name); pcb[k].priority=pcb1[t].priority; pcb[k].runtime=pcb1[t].runtime; k=k+1; for(j=t;j<r;j++) { strcpy(pcb1[j].name,pcb1[j+1].name); pcb1[j].priority=pcb1[j+1].priority; pcb1[j].runtime=pcb1[j+1].runtime; } r=r-1; printf("就绪进程:\n"); for(j=0;j<k;j++) printf("%s%d%d\n",pcb[j].name,pcb[j].priority,pcb[j].runtime); printf("堵塞进程:\n"); for(j=0;j<r;j++) printf("%s%d%d\n",pcb1[j].name,pcb1[j].priority,pcb1[j].runtime); break; } else printf("该堵塞进程为空,不能唤醒进程!\n"); break; } } if(x==4) { printf("终止进程\n");printf("请输入你要终止的进程:"); scanf("%s",name); for(i=0;i<k;i++) { if(strcmp(pcb[i].name,name)==0) { t=i; for(j=t;j<k;j++) { strcpy(pcb[j].name,pcb[j+1].name); pcb[j].priority=pcb[j+1].priority; pcb[j].runtime=pcb[j+1].runtime; } k=k-1; } if(strcmp(pcb1[i].name,name)==0) { t=i; for(j=t;j<r;j++) { strcpy(pcb1[j].name,pcb1[j+1].name); pcb1[j].priority=pcb1[j+1].priority; pcb1[j].runtime=pcb1[j+1].runtime; } r=r-1; } } printf("就绪进程:\n"); for(j=0;j<k;j++) printf("%s%d%d\n",pcb[j].name,pcb[j].priority,pcb[j].runtime); printf("堵塞进程:\n"); for(j=0;j<r;j++) printf("%s%d%d\n",pcb1[j].name,pcb1[j].priority,pcb1[j].runtime); } if(x==5) { printf("显示进程\n"); printf("就绪进程:\n"); for(j=0;j<k;j++) printf("%s%d%d\n",pcb[j].name,pcb[j].priority,pcb[j].runtime); printf("堵塞进程:\n"); for(j=0;j<r;j++) printf("%s%d%d\n",pcb1[j].name,pcb1[j].priority,pcb1[j].runtime); } }}程序运行结果实训小结:通过设计并调试创建、终止、阻塞、唤醒原语功能,加深了对操作系统中进程控制功能的理解,并且掌握操作系统模块的设计方法和工作原理。更重要的是理解了操作系统的调度方法是就绪-运行-堵塞-唤醒-结束的过程。
实训二:模拟动态分区首次适应分配和回收算法实训目的:通过本实训,可加深理解动态分区分配、回收程序的功能和具体实现,特别是对回收分区的合并的理解。实训内容:1、设计动态分区首次适应分配、回收算法。2、设计“未分配区说明表”,格式为:序号始址长度状态160k200103、设计“已分配区说明表”,格式为:作业名始址长度状态004、设计显示程序,将“未分配区说明表”和“已分配区说明表”的内容显示在屏幕上。初始分配从一个空闲区分配起,回收时要合并空区。实训步骤:1、系统要求分配一个分区时,应输入:作业名、作业长度。2、回收一个分区时,应输入:回收的作业名。回收的分区请注意是否需要进行合并。实训代码:#include<STDIO.H>#include<STDLIB.H>intMAX_SEGMENT=10;//最大碎片值structPartition //分区表目{ intPar_Size; //分区大小 intPar_No; //分区序号或者名字 intAddr; //分区地址 intIsUse; //分区使用情况,0表示空闲,1表示使用 Partition*pri; //前向指针 Partition*next; //后向指针};Partition*Int()//函数,返回Partition类型指针{ //初始化空闲分区表 Partition*list,*H,*H1; list=(structPartition*)malloc(sizeof(structPartition));//malloc申请动态分配空间 list->next=NULL; H=list; if(!list) { printf("\n错误,内存初始化分配失败!程序结束"); exit(1); } H1=(structPartition*)malloc(sizeof(structPartition)); printf("请预先输入分区总大小(以KB为单位):"); scanf("%d",&H1->Par_Size); H1->Addr=0; H1->Par_No=0; H1->IsUse=0; H1->pri=H; H1->next=NULL; H->next=H1;////list>H1 returnlist;}Partition*InitFP(){ //初始化已分配分区表 Partition*FP,*F,*H; inti; FP=(structPartition*)malloc(sizeof(structPartition)); FP->next=NULL; H=FP; for(i=0;i<10;i++) //已分配区先暂定分配十个表目 { F=(structPartition*)malloc(sizeof(structPartition)); if(!F) { printf("\n错误,内存分配失败!程序结束"); exit(1); } F->Par_Size=0; F->Addr=0; F->Par_No=0; F->IsUse=0; F->next=NULL; H->next=F; F->pri=H; H=H->next; } returnFP;}Partition*New_Process(Partition*list,Partition*FP){ //为新的进程分配资源 Partition*H,*P,*H1; intSize,Name,L; H=list; H1=FP->next; H=H->next; printf("请输入新作业的名称和大小(整数)\n"); printf("作业名称:"); scanf("%d",&Name); printf("作业大小(整数):"); scanf("%d",&Size); while(H) { if(!H) //表目已查完,无法分配 { printf("\n已无空闲分区,本次无法分配!"); returnlist; } else{ if(H->IsUse==0) //空表目 //if(H->Par_Size>=Size) //大小满足,空闲分区大小》要分配的大小 if(H->Par_Size>=Size) //大小满足, { booltemp=false;//空闲分区大小-要分配的大小<碎片值//会产生碎片,将整块内存大小分配出去, if((H->Par_Size-Size)<=MAX_SEGMENT){ Size=H->Par_Size;//分配的大小为整块内存 temp=true;//会产生碎片 } //其他情况就分配大小为请求大小,不会产生碎片, L=H->Addr;//保存空闲分地址 if(temp) printf("该次分配会产生碎片,大小为%d的内存分配出去!",Size);else printf("该次内存分配不会产生碎片"); break; } } H=H->next; //否则,继续往下查找 } if(H) { if(H->Par_Size>Size) //大小满足,空闲分区大小》要分配的大小 {//分配新的表目,处理一条数据,分配一次内存 P=(structPartition*)malloc(sizeof(structPartition)); P->IsUse=1; P->Addr=L;//指向空闲分区地址 P->next=H; //修改指针 H->pri->next=P; P->pri=H->pri; H->pri=P; P->Par_Size=Size;//分配大小为要请求分配的大小 P->Par_No=Name;//名称 H->Par_Size-=Size; //修改空闲分区,H所指区块大小减Size H->Addr+=Size;//H所指区块地址加Size }else { H->IsUse=1; //大小相等的,把当前表项设置空表目 } while(H1) { if(H1->IsUse==0) { H1->Par_No=Name; H1->Par_Size=Size; H1->Addr=L;//保存已分配地址 H1->IsUse=1;//在已分配表中设置为已分配 break; } H1=H1->next; } }else printf("所申请资源已大过系统所拥有的,请重新输入!\n"); returnlist;}Partition*Reclaim(Partition*list,Partition*FP){ //结束作业,资源回收,No为作业名,回收内存Partition*H1,*H2,*H3,*HF;//H1为释放区,H2为后分区,H3为前分区 intNo; //作业名 H1=list; HF=FP;//可有可无? H1=H1->next; HF=FP->next; printf("请输入您想结束的作业名:"); scanf("%D",&No); while(HF)//对已分配表进行操作 { if(HF->Par_No==No) { HF->IsUse=0; //标志为空表目 break;//这时保存着HF所指分区的信息 } HF=HF->next; } if(!HF) //如果找不到该作业,则提示出错 printf("所输入的作业名称不正确,请重新输入!"); else{ while(H1)//对空闲表进行操作 { if(H1->Par_No==No) { H1->IsUse=0; //标志为空表目 printf("内存回收成功"); break; } H1=H1->next; } H2=H1->next;//后分区 H3=H1->pri;//前分区 if(H2&&H2->IsUse==0) //后接分区为空闲 { if(H2->next==NULL) //判断后接分区是否为尾结点 { H1->Par_Size+=H2->Par_Size; //把H2合并到H1 H1->next=NULL; free(H2); printf("已回收%d大小内存",H1->Par_Size); }else //后分区不为空闲,表示已经被使用 { H1->Par_Size+=H2->Par_Size; H1->next=H2->next; H2->next->pri=H1; free(H2); printf("已回收%d大小内存",H1->Par_Size); } } if(H3&&H3->IsUse==0) //前分区为空闲分区,则合并去前分区 { H3->Par_Size+=H1->Par_Size; H3->next=H1->next; if(H1->next!=NULL) //若H1为尾结点 H1->next->pri=H3; free(H1); printf("已回收%d大小内存",H1->Par_Size); } } returnlist;}voidPrint(Partition*list,Partition*FP){ //输出已分配分区和空闲分区 Partition*H1,*H2; H1=list->next; H2=FP; H2=H2->next; printf("**************************************************\n"); printf("****************总分配分区表*******************\n"); printf("分区序号 大小 开始地址状态\n"); while(H1) { printf("%d %d %d",H1->Par_No,H1->Par_Size,H1->Addr); if(H1->IsUse==1) printf(" 已分配\n"); else printf(" 空表目\n"); H1=H1->next; } printf("**************************************************\n");}voidMain_Print(Partition*list,Partition*FP){ //程序主入口函数,进行菜单选择 intop; while(1) { printf("\n主菜单\n"); printf("\n"); printf("1.申请新的作业,分配内存\n"); printf("2.结束作业,回收内存\n"); printf("3.查看内存表\n"); printf("4.退出系统\n"); printf("\n请选择<1-4>:"); scanf("%d",&op); switch(op) //根据输入,选择分支方向 { case1: New_Process(list,FP); break; case2: Reclaim(list,FP); break; case3: Print(list,FP); break; case4: break; default: printf("\n选择错误,请重新选择!"); break; } if(op==4) break; //退出循环 }}voidmain(){ //主函数入口 structPartition*list,*FP; list=Int(); FP=InitFP(); Main_Print(list,FP);}程序运行结果实训小结:通过本实训,加深了对动态分区分配、回收程序的功能和具体实现,特别是对回收分区的合并的理解,同时对于内存碎片的产生和整理有了更为深入的了解。实训三:模拟实现银行家算法判断系统的状态实训目的:了解进程管理的实现方法,理解和掌握处理进程同步问题的方法。实训内容:实现银行家算法、进程调度过程的模拟、消费者--供应商的供应商优先算法。实训步骤:1、理解安全性算法和银行家算法的核心机制。2、理解进程的三状态调度过程,及各状态间的转换关系。3、设计消费者--供应商的供应商优先算法。实训代码:#include<stdio.h>#include<stdlib.h>#include<conio.h>#definem50intno1;//进程数intno2;//资源数intr;intallocation[m][m],need[m][m],available[m],max[m][m];charname1[m],name2[m];//定义全局变量voidmain(){ voidcheck(); voidprint(); inti,j,p=0,q=0; charc; intrequest[m],allocation1[m][m],need1[m][m],available1[m]; printf("银行家算法\n");printf("请输入进程总数:"); scanf("%d",&no1); printf("请输入资源种类数:"); scanf("%d",&no2);printf("请输入最大需求矩阵:\n"); for(i=0;i<no1;i++) for(j=0;j<no2;j++) scanf("%d",&max[i][j]);//输入已知进程最大资源需求量 printf("请输入当前分配矩阵:\n"); for(i=0;i<no1;i++) for(j=0;j<no2;j++) scanf("%d",&allocation[i][j]);//输入已知的进程已分配的资源数 for(i=0;i<no1;i++) for(j=0;j<no2;j++) need[i][j]=max[i][j]-allocation[i][j];//根据输入的两个数组计算出need矩阵的值 printf("请输入可利用资源矩阵\n"); for(i=0;i<no2;i++) scanf("%d",&available[i]);//输入已知的可用资源数 print();//输出已知条件 check();//检测T0时刻已知条件的安全状态 if(r==1)//如果安全则执行以下代码 { do{ q=0;p=0; printf("\n请输入请求资源的进程号(0~4):\n"); for(j=0;j<=10;j++) { scanf("%d",&i); if(i>=no1) { printf("输入错误,请重新输入:\n"); continue; } elsebreak; } printf("\n请输入该进程所请求的资源数request[j]:\n"); for(j=0;j<no2;j++) scanf("%d",&request[j]); for(j=0;j<no2;j++) if(request[j]>need[i][j])p=1; //判断请求是否超过该进程所需要的资源数 if(p) printf("请求资源超过该进程资源需求量,请求失败!\n"); else { for(j=0;j<no2;j++) if(request[j]>available[j])q=1;//判断请求是否超过可用资源数 if(q) printf("没有做够的资源分配,请求失败!\n"); else//请求满足条件 { for(j=0;j<no2;j++) { available1[j]=available[j]; allocation1[i][j]=allocation[i][j]; need1[i][j]=need[i][j]; //保存原已分配的资源数,仍需要的资源数和可用的资源数 available[j]=available[j]-request[j]; allocation[i][j]+=request[j]; need[i][j]=need[i][j]-request[j];//系统尝试把资源分配给请求的进程 } print(); check();//检测分配后的安全性 if(r==0)//如果分配后系统不安全 { for(j=0;j<no2;j++) { available[j]=available1[j]; allocation[i][j]=allocation1[i][j]; need[i][j]=need1[i][j]; //还原已分配的资源数,需要的资源数和可用的资源数 } printf("返回分配前资源数\n"); print(); } } }printf("\n你还要继续分配吗?YorN?\n"); //判断是否继续进行资源分配 c=getche(); }while(c=='y'||c=='Y'); }}voidcheck()//安全算法函数{ intk,f,v=0,i,j; intwork[m],a[m]; boolfinish[m]; r=1; for(i=0;i<no1;i++) finish[i]=false;//初始化进程均没得到足够资源数并完成 for(i=0;i<no2;i++) work[i]=available[i];//work[i]表示可提供进程继续运行的各类资源数 k=no1; do{ for(i=0;i<no1;i++) { if(finish[i]==false) { f=1; for(j=0;j<no2;j++) if(need[i][j]>work
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 公路项目人员聘请合同范本
- 农村房屋安装维修合同范本
- 公司员工劳动合同范本
- 北京企业住房合同范本
- 产品交付标准合同范本
- 公司担保合同范本6
- 综合实践项目《制作细胞模型》教学设计-2024-2025学年鲁科版生物六年级上册
- 2人合伙合同范本
- 修路混凝土合同范本
- 产品加工定制合同范本
- 运输车辆卫生安全检查记录表
- 民航概论PPT全套教学课件
- 过敏性肺泡炎课件
- 客运车辆进站协议书
- 药学专业论文3000字-药学毕业论文
- 2022-2023学年辽宁省葫芦岛市建昌县数学四下期末经典试题含解析
- 山东工商学院马克思主义基本原理期末复习题及参考答案
- 2022-2023学年杭州市六年级下学期数学期末考试试卷及答案解析
- 文献检索与论文写作-文献检索与科技论文写作138课件
- 公务员录用审批表
- 重庆市住宅装饰装修工程质量验收标准
评论
0/150
提交评论