1、操作系统原理实 验 报 告院 (部): 管理工程学院专 业:信息管理与信息系统实验项目:实验一 二 三 五班 级:信管 102姓 名:张凤丹学 号:20100214182目 录引 言 4实验一、模拟进程创建、终止、阻塞、唤醒原语 6实验目的: 6实验内容: 6实验步骤: 7实验代码: 7程序运行结果及分析 12实验感想: .13实验二、模拟进程调度功能 14实验目的: 14实验内容: 14实验步骤: 14实验代码: 15程序运行结果及分析 19实验感想: .20实验三:模拟动态分区首次适应分配和回收算法 20实验目的: 20实验内容: 20实验步骤: 20实验代码: 21程序运行结果及分析 2
2、7实验感想: .28实验五:模拟使用银行家算法判断系统的状态 28实验目的: 28实验步骤: 28实验代码: 28程序运行结果及分析 33实验感想: .343引 言操作系统是信息管理与信息系统专业一门重要的专业理论课程,了解和掌握操作系统的基本概念、功能和实现原理,对认识整个计算机系统的工作原理十分重要。操作系统实验是操作系统课程的一个重要组成部分,通过试验环节的锻炼使同学们不仅能够对以前的所学过的基础知识加以巩固,同时能够通过上机实验,对操作系统的抽象理论知识加以理解,最终达到融会贯通的目的,因此,实验环节是同学们理解、掌握操作系统基本理论的一个重要环节。本实验指导书,根据教材中的重点内容设
3、定了相应的实验题目,由于实验课程的学时有限,我们规定了必做题目和选做题目,其中必做题目必须在规定的上机学时中完成,必须有相应的预习报告和实验报告。选做题目是针对有能力或感兴趣的同学利用课余时间或上机学时的剩余时间完成。56实验一、模拟进程创建、终止、阻塞、唤醒原语实验目的:通过设计并调试创建、终止、阻塞、唤醒原语功能,有助于对操作系统中进程控制功能的理解,掌握操作系统模块的设计方法和工作原理。实验内容:1、设计创建、终止、阻塞、唤醒原语功能函数。2、设计主函数,采用菜单结构(参见后面给出的流程图) 。73、设计“显示队列”函数,目的能将就绪、阻塞队列中的进程信息显示在屏幕上,以供随时查看各队列
4、中进程的变化情况。实验步骤:1、进程 PCB 中应包含以下内容:进程名优先级运行时间状态指针2、系统总体结构:系统主菜单1创建2阻塞3唤醒4终止5显示0退出请输入您需要的功能(05):实验代码:#include #includestruct PCBchar name4;int priority;其中:进程名用 P1,P2 标识。优先级及运行时间:为实验题目二做准备。状态为:就绪、运行、阻塞,三种基本状态。指针:指向下一个 PCB。输入选择=?创建 阻塞 唤醒 终止 显示退出开始结束0 1 2 3 4 58int runtime;void main()int x,t;int a=0;int k=
5、0,r=1,i=0,j=0;/k 为就绪队列总数,r 堵塞队列总数char name4;struct PCB pcb10;struct PCB pcb110;struct PCB pcb210;printf(“-菜单-nnn“);printf(“0-退出系统n“);printf(“1-创建进程n“);printf(“2-堵塞进程n“);printf(“3-唤醒进程n“); printf(“4-终止进程n“);printf(“5-显示进程n“);printf(“-n“);strcpy(pcb10.name,“s“);/堵塞队列pcb10.priority = 2;pcb10.runtime =
6、3;/printf(“%s %d %d“,pcb10.name,pcb10.priority,pcb10.runtime);while(1)printf(“请输入你的选择:“);scanf(“%d“,if(x=0)break;if(x=1)printf(“-创建进程-n“); 9printf(“进程名:“);scanf(“%s“,printf(“优先级:“);scanf(“%d“,printf(“运行时间:“);scanf(“%d“,k=k+1;if(x=2)printf(“-堵塞进程-n“); printf(“请输入要查找的进程:“);scanf(“%s“,name);for(j=0;j#i
7、ncludevoid priority();void time();struct PCBchar name4;int priority;int runtime;struct PCB pcb5;int q=5;void main() int p,i;strcpy(pcb0.name,“p1“);/序列队列,优先级由高到低为 1,2,3.pcb0.priority = 2;pcb0.runtime = 3;strcpy(pcb1.name,“p2“);/序列队列pcb1.priority = 3;pcb1.runtime = 2;strcpy(pcb2.name,“p3“);/序列队列pcb2.p
8、riority = 1;pcb2.runtime = 4;strcpy(pcb3.name,“p4“);/序列队列pcb3.priority = 5;pcb3.runtime = 6;strcpy(pcb4.name,“p5“);/序列队列pcb4.priority = 4;pcb4.runtime = 5;printf(“-进程调度子菜单-n“);printf(“ 0-退出系统 n“);17printf(“ 1-优先级调度 n“);printf(“ 2-时间片调度 n“);printf(“nn 显示所有进程n“);for(i=0;ipcbj.priority) 18strcpy(name,p
9、cbi.name);strcpy(pcbi.name,pcbj.name);strcpy(pcbj.name,name);t=pcbi.priority;pcbi.priority=pcbj.priority;pcbj.priority=t;r=pcbi.runtime;pcbi.runtime=pcbj.runtime;pcbj.runtime=r;printf(“按优先级高低进行排序n“);for(i=0;i#include int MAX_SEGMENT=10;/最大碎片值struct Partition /分区表目int Par_Size; /分区大小int Par_No; /分区序号
10、或者名字int Addr; /分区地址int IsUse; /分区使用情况,0 表示空闲,1 表示使用Partition *pri; /前向指针Partition *next; /后向指针;Partition * Int()/函数,返回 Partition 类型指针 /初始化空闲分区表Partition *list,*H,*H1;list=(struct Partition *)malloc(sizeof(struct Partition);/malloc 申请动态分配空间list-next=NULL;H=list;if(!list)printf(“n 错误,内存初始化分配失败!程序结束“);
11、exit(1);H1=(struct Partition *)malloc(sizeof(struct Partition);printf(“请预先输入分区总大小(以 KB 为单位) :“);scanf(“%d“,H1-Addr=0;H1-Par_No=0;H1-IsUse=0;H1-pri=H;H1-next=NULL;H-next=H1;/list-H1return list;Partition * InitFP() /初始化已分配分区表Partition *FP,*F,*H;23int i;FP=(struct Partition *)malloc(sizeof(struct Parti
12、tion);FP-next=NULL;H=FP;for(i=0;iPar_Size=0;F-Addr=0;F-Par_No=0;F-IsUse=0;F-next=NULL;H-next=F;F-pri=H;H=H-next;return FP;Partition * New_Process( Partition *list, Partition *FP) /为新的进程分配资源Partition *H,*P,*H1;int Size,Name,L;H=list;H1=FP-next;H=H-next;printf(“请输入新作业的名称和大小(整数)n“);printf(“作业名称:“);scan
13、f(“%d“,printf(“作业大小(整数):“);scanf(“%d“,while(H)if(!H) /表目已查完,无法分配printf(“n 已无空闲分区,本次无法分配!“);return list;elseif(H-IsUse=0) /空表目24/if(H-Par_Size=Size) /大小满足 ,空闲分区大小要分配的大小if(H-Par_Size=Size) /大小满足 ,bool temp=false;if(H-Par_Size-Size)Par_Size;/分配的大小为整块内存temp=true;/会产生碎片/其他情况就分配大小为请求大小,不会产生碎片,L=H-Addr;/保存
14、空闲分地址if(temp)printf(“该次内存分配会产生碎片,将整块内存大小%d 分配出去!“,Size);elseprintf(“该次内存分配不会产生碎片“);break; H=H-next; /否则,继续往下查找if(H)if(H-Par_SizeSize) /大小满足,空闲分区大小 要分配的大小P=(struct Partition *)malloc(sizeof(struct Partition); /分配新的表目,处理一条数据,分配一次内存P-IsUse=1;P-Addr=L;/指向空闲分区地址P-next=H; /修改指针H-pri-next=P;P-pri=H-pri;H-p
15、ri=P;P-Par_Size=Size;/分配大小为要请求分配的大小P-Par_No=Name;/名称H-Par_Size-=Size; /修改空闲分区,H 所指区块大小减 SizeH-Addr+=Size;/H 所指区块地址加 SizeelseH-IsUse=1; /大小相等的,把当前表项设置空表目while(H1)25if(H1-IsUse=0)H1-Par_No=Name;H1-Par_Size=Size;H1-Addr=L;/保存已分配地址H1-IsUse=1;/在已分配表中设置为已分配break;H1=H1-next;elseprintf(“所申请资源已大过系统所拥有的,请重新输入
16、!n“);return list;Partition *Reclaim( Partition *list, Partition *FP) /结束作业,资源回收,No 为作业名,回收内存Partition * H1,*H2,*H3,*HF;/H1 为释放区,H2 为后分区,H3 为前分区int No; /作业名H1=list;HF=FP;/可有可无?H1=H1-next;HF=FP-next;printf(“请输入您想结束的作业名:“);scanf(“%D“,while(HF)/对已分配表进行操作if(HF-Par_No=No)HF-IsUse=0; /标志为空表目break;/这时保存着 HF
17、 所指分区的信息HF=HF-next;if(!HF) /如果找不到该作业,则提示出错printf(“所输入的作业名称不正确,请重新输入!“);elsewhile(H1)/对空闲表进行操作if(H1-Par_No=No)H1-IsUse=0; /标志为空表目printf(“内存回收成功“);break;26H1=H1-next;H2=H1-next;/后分区H3=H1-pri;/前分区if(H2 /把 H2 合并到 H1H1-next=NULL;free(H2);printf(“已回收%d 大小内存“,H1-Par_Size);else /后分区不为空闲,表示已经被使用H1-Par_Size+=
18、H2-Par_Size;H1-next=H2-next;H2-next-pri=H1;free(H2);printf(“已回收%d 大小内存“,H1-Par_Size);if(H3H3-next=H1-next;if(H1-next!=NULL) /若 H1 为尾结点H1-next-pri=H3;free(H1);printf(“已回收%d 大小内存“,H1-Par_Size);return list;void Print( Partition *list, Partition *FP) /输出已分配分区和空闲分区 Partition *H1,*H2;H1=list-next;H2=FP;H2
19、=H2-next;printf(“*n“);printf(“*总分配分区表*n“);printf(“分区序号 大小 开始地址 状态n“);while(H1)27printf(“%d %d %d“,H1-Par_No,H1-Par_Size,H1-Addr);if(H1-IsUse=1)printf(“ 已分配n“);elseprintf(“ 空表目n“);H1=H1-next;printf(“*n“);void Main_Print( Partition *list, Partition *FP) /主入口函数,进行菜单选择int op;while(1)printf(“n-主菜单-n“);pr
20、intf(“n“);printf(“1.申请新的作业,分配内存n“);printf(“2.结束作业,回收内存n“);printf(“3.查看内存表n“);printf(“4.退出系统n“);printf(“n 请选择:“);scanf(“%d“,switch(op) /根据输入,选择分支方向case 1: New_Process(list,FP);break;case 2: Reclaim(list,FP);break;case 3:Print(list,FP);break;case 4:break;default:printf(“n 选择错误,请重新选择!“);break;if(op=4)b
21、reak; /退出循环void main()28 /主函数入口struct Partition *list,*FP;list=Int();FP=InitFP();Main_Print(list,FP);程序运行结果及分析29实验感想:通过本实验,加深了对动态分区分配、回收程序的功能和具体实现,特别是对回收分区的合并的理解。实验五:模拟使用银行家算法判断系统的状态实验目的:了解进程管理的实现方法,理解和掌握处理进程同步问题的方法。实验内容:实现银行家算法、进程调度过程的模拟、读者-写者问题的写者优先算法。实验步骤: 理解安全性算法和银行家算法的核心机制: 理解进程的三状态调度过程,及各状态间的转
22、换关系;30 设计读者-写者问题的写者优先算法;实验代码:#include #include #include # define m 50int no1; /进程数int no2; /资源数int r;int allocationmm,needmm,availablem,maxmm; char name1m,name2m; /定义全局变量void main()void check();void print();int i,j,p=0,q=0;char c;int requestm,allocation1mm,need1mm,available1m;printf(“-银行家算法-n“);prin
23、tf(“请输入进程总数:“);scanf(“%d“,printf(“请输入资源种类数:“);scanf(“%d“,printf(“请输入最大需求矩阵:n“);for(i=0;ino1;i+)for(j=0;jno2;j+)scanf(“%d“, /输入已知进程最大资源需求量printf(“请输入当前分配矩阵:n“);for(i=0;ino1;i+)for(j=0;jno2;j+)scanf(“%d“, /输入已知的进程已分配的资源数for(i=0;ino1;i+)for(j=0;jno2;j+)needij=maxij-allocationij; /根据输入的两个数组计算出 need 矩阵的值printf(“请输入可利用资源矩阵n“);