1、操作系统实验源码参考终版含文件系统实验试验一 进程调度一、实验目的:编写和调试一个进程调度程序,以加深对进程的概念及进程调度算法的理解。 二、实验内容:以两种典型算法为例说明实现的算法(一)、最高优先数优先的调度算法1、实验原理进程调度算法:采用最高优先数优先的调度算法(即把处理机分配给优先数最高的进程)和先来先服务算法。 每个进程有一个进程控制块(PCB)表示。进程控制块可以包含如下信息:进程名、优先数、到达时间、需要运行时间、已用CPU时间、进程状态等等。 进程的优先数及需要的运行时间可以事先人为地指定(也可以由随机数产生)。进程的到达时间为进程输入的时间。 进程的运行时间以时间片为单位进
2、行计算。 每个进程的状态可以是就绪 W(Wait)、运行R(Run)、或完成F(Finish)三种状态之一。 就绪进程获得CPU后都只能运行一个时间片。用已占用CPU时间加1来表示。 如果运行一个时间片后,进程的已占用 CPU时间已达到所需要的运行时间,则撤消该进程,如果运行一个时间片后进程的已占用CPU时间还未达所需要的运行时间,也就是进程还需要继续运行,此时应将进程的优先数减1(即降低一级),然后把它插入就绪队列等待CPU。每进行一次调度程序都打印一次运行进程、就绪队列、以及各个进程的 PCB,以便进行检查。 重复以上过程,直到所有进程都完成为止。2、源代码:#include stdio.
3、h #include #include #define getpch(type) (type*)malloc(sizeof(type) #define NULL 0 struct pcb /* 定义进程控制块PCB */ char name10; /*定义进程名称*/ char state; /*进程状态*/ int super; /*优先数*/ int ntime; /*需要运行的时间*/ int rtime; /*已占用的CPU时间*/ struct pcb* link; *ready=NULL,*p; typedef struct pcb PCB; /*pcb表*/ sort() /*
4、建立对进程进行优先级排列函数*/ PCB *first, *second; int insert=0; if(ready=NULL)|(p-super)(ready-super) /*优先级最大者,插入队首*/ p-link=ready; ready=p; else /* 进程比较优先级,插入适当的位置中*/ first=ready; second=first-link; while(second!=NULL) if(p-super)(second-super) /*若插入进程比当前进程优先数大,*/ /*插入到当前进程前面*/ p-link=second; first-link=p; sec
5、ond=NULL; insert=1; else /* 插入进程优先数最低,则插入到队尾*/ first=first-link; second=second-link; if(insert=0) first-link=p; input() /* 建立进程控制块函数*/ int i,num; clrscr(); /*清屏*/ printf(n 请输入进程号?); scanf(%d,&num); for(i=0;iname); printf(n 输入进程优先数:); scanf(%d,&p-super); printf(n 输入进程运行时间:); scanf(%d,&p-ntime); print
6、f(n); p-rtime=0;p-state=w; p-link=NULL; sort(); /* 调用sort函数*/ int space() int l=0; PCB* pr=ready; while(pr!=NULL) l+; pr=pr-link; return(l); disp(PCB * pr) /*建立进程显示函数,用于显示当前进程*/ printf(n qname t state t super t ndtime t runtime n); printf(|%st,pr-name); printf(|%ct,pr-state); printf(|%dt,pr-super);
7、printf(|%dt,pr-ntime); printf(|%dt,pr-rtime); printf(n); check() /* 建立进程查看函数,检查等待队列的进程是否进入就绪队列*/ PCB* pr; printf(n * 当前正在运行的进程是:%s,p-name); /*显示当前运行进程*/ disp(p); pr=ready; printf(n *当前就绪队列状态为:n); /*显示就绪队列状态*/ while(pr!=NULL) disp(pr); pr=pr-link; destroy() /*建立进程撤消函数(进程运行结束,撤消进程)*/ printf(n 进程 %s 已完
8、成.n,p-name); free(p); running() /* 建立进程就绪函数(进程运行时间到,置就绪状态*/ (p-rtime)+; if(p-rtime=p-ntime) destroy(); /* 调用destroy函数*/ else (p-super)-; p-state=w; sort(); /*调用sort函数*/ main() /*主函数*/ int len, h=0; char ch; input(); len=space(); while(len!=0)&(ready!=NULL) ch=getchar(); h+; printf(n The execute numb
9、er:%d n,h); p=ready; ready=p-link; p-link=NULL; p-state=R; check(); running(); printf(n 按任一键继续.); ch=getchar(); printf(nn 进程已经完成.n); ch=getchar(); 3、运行结果:请输入进程号?5进程号No.0:输入进程名:A输入进程优先数:2输入进程运行时间:1进程号No.1:输入进程名:B输入进程优先数:3输入进程运行时间:1进程号No.2:输入进程名:C输入进程优先数:1输入进程运行时间:1进程号No.3:输入进程名:D输入进程优先数:4输入进程运行时间:1进程
10、号No.4:输入进程名:E输入进程优先数:5输入进程运行时间:1The execute number:1*当前正在运行的进程是:EQname state super ndtime runtimeE R 5 1 0*当前就绪队列状态为:Qname state super ndtime runtimeD w 4 1 0B w 3 1 0A w 2 1 0C w 1 1 0进程E已完成按任一键继续The execute number:2*当前正在运行的进程是:DQname state super ndtime runtimeD R 4 1 0*当前就绪队列状态为:Qname state super
11、ndtime runtimeB w 3 1 0A w 2 1 0C w 1 1 0进程D已完成按任一键继续The execute number:3*当前正在运行的进程是:BQname state super ndtime runtimeB R 3 1 0*当前就绪队列状态为:Qname state super ndtime runtimeA w 2 1 0C w 1 1 0进程B已完成按任一键继续The execute number:4*当前正在运行的进程是:AQname state super ndtime runtimeA R 2 1 0*当前就绪队列状态为:Qname state sup
12、er ndtime runtimeC w 1 1 0进程A已完成按任一键继续The execute number:5*当前正在运行的进程是:cQname state super ndtime runtimec R 1 1 0*当前就绪队列状态为:进程C已完成按任一键继续进程已经完成(二)、简单轮转法1、实验原理在分时系统中,都毫无例外采用时间片轮转法。在一种简单的轮转法中,系统将所有就绪进程按FIFO规则排成一个队列,把CPU分配给队首进程,并规定它执行一给定的时间如100ms,称此时间间隔为时间片。当时间片完成时,系统产生一个时钟中断,剥夺该进程的执行,将它送至就绪队列的末尾,并把处理机分配
13、给就绪队列的新队首进程,同样也让它执行一个时间片。这样,就绪队列中的所有进程均可获得一个时间片的处理机而运行。就绪队列中的进程在依次执行时,可能发生以下三种情况:(1)进程未用完一个时间片就结束,这时系统应提前调度;(2)进程在执行过程中提出I/O请求而阻塞,系统应将它放入相应的阻塞队列并引起调度;(3)进程完成一个时间片后尚未完成,系统应将它重新放到就绪队列的末尾,等待下次执行。由于在分时系统中,键盘命令的执行时间较短,大多能在一个时间片内执行完毕,因此分时系统的实际响应时间将比Nq(N是同时性用户数,q是时间片大小)小。2、源代码:#include/*定义一个pcb的结构体*/struct
14、 pcb char name; /*进程名*/int time; /*进程执行时间*/; void main() int n,i,j,flag=1; struct pcb a100; /*最多可以有100个进程*/printf(输入进程 个数:); scanf(%d,&n); getchar();/*接收回车*/ for(i=0;i0) /*若进程数为空,结束程序*/ if(ai.time!=0) /*就绪队列是否为空*/ printf(%c,ai.name); /*进程执行一次,打印出该进程*/ai.time-; /*使该进程占用的时间片减1*/ for(j=0;jn;j+) if(aj.t
15、ime) /*若进程所占用的时间片不为0,仍执行下一进程*/ flag=1; break; else /*若进程所占用的时间片为0,说明已经完成,跳过执行下一进程*/flag=0; i=(+i)%n; /*继续执行下一个进程,i1*/ printf(n);3、运行结果:输入进程个数:5输入进程的名字:A输入占用的时间片:2输入进程的名字:B输入占用的时间片:3输入进程的名字:C输入占用的时间片:1输入进程的名字:D输入占用的时间片:4输入进程的名字:E输入占用的时间片:5ABCDEABDEBDEDEEPress any key to continue 实验二 存储管理一.实验目的:存储管理的主
16、要功能之一是合理分配空间,请求页式管理是一种常用的虚拟存储管理技术。本实验的目的是通过请求页式管理中的页面置换算法设计,了解虚拟存储技术的特点,掌握请求页式管理的页面置换算法。二.实验内容:1、分区管理的原理:将存储器划分成若干段大小固定的区域,一个区域里只能运行一个程序,程序只能在其自身所在的分区中活动。 2、固定式分区管理的原理:区域大小及起始地址是固定的。一个分区只能存放一个程序。需要设置一个分区说明表来标明内存的使用状态。根据分区说明表来给程序分配相应的区域。由于程序不可能刚刚占有一个分区的大小 ,这样就会在一个分区之中留下零头,造成了极大的浪费。 3、可变式分区管理的原理:区域的大小
17、及起始地址是可变的,根据程序装入时的大小动态地分配一个区域。保证每个区域之中刚好放一个程序。这样可以充分地利用存储空间,提高内存的使用效率。如果一个程序运行完毕,就要释放出它所占有的分区,使之变成空闲区。这样就会出现空闲区与占用区相互交错的情况。这样就需要P表,F表来分别表示内存的占用区状态与空闲区的状态。(一)、设计一个固定式分区分配的存储管理方案,并模拟实现分区的分配和回收过程。1.通过随机数产生一个程序指令序列,使得50%的指令是顺序执行的。25%的指令是均匀分布在前地址部分,25%的指令是均匀分布在后地址部分。2.FIFO算法总是选择在内存驻留时间最长的一页将其淘汰。FIFO算法认为先
18、调入内存的页不再被访问的可能性要比其他页大,因而选择最先调入内存的页换出。实现FIFO算法需要把各个已分配页面按分配时间顺序记录在一个数组中,每次淘汰最早进入数组的页。3、程序代码如下:#include #include#define maxsize 32#include #define vpf 200void FIFO(int a);int countmaxsize;int avpf;void main() / 定义主函数for(int i=0;i200;i+) / 用随机数产生页地址流 ai=rand()%32;FIFO(a);void FIFO(int a) / FIFO算法 for(i
19、nt n=4;n33;n+) /不同的页面数计算命中率 int num; int max; int maxpage=0; int dis=0; int i=0; int k=0; int sum=n; int bmaxsize; for (k=0;kn;k+) / 页面数组,计数数组初始化 bk=-1; countk=0; for (i=0;ivpf;i+) num=0; for (k=0;kn;k+) / 测试是否命中 if(ai=bk) num+; if(num=0) /未命中 dis+; for(k=0;kn;k+) / 所有页面计数器加一 countk+; if(sum=0) /没空白
20、页面时 max=0; for(k=0;kn;k+) if(maxcountk) / 找出计数器值最大的替换 max=countk; maxpage=k; bmaxpage=ai; countmaxpage=0; /被替换页面计数器清零 else bn-sum=ai; countn-sum=0; /有空白页面时,将所缺页放入空白页面, sum-; / 并将该页面计数器清零 printf(%d,n); printf( page frames FIFO:%3d,dis); printf( FIFO:%6.4fn,1-(float)dis/32);运行结果(二)、编写并调试一个断式存储管理的地址转换的
21、模拟程序。最佳适应算法#include #include struct freeMint Sadd; int length;struct busyMEMint Sadd; int Eadd; char fill; busyMEM *next;class Assignpublic: void initMEM(); void pai(); void printList(); void resetfree(); void insert(); void Delete();private: freeM freeMEM20; busyMEM *p;void Assign:initMEM() p=(busy
22、MEM*)malloc(sizeof(busyMEM); busyMEM *L; L=p; L-fill=O; L-Eadd=19; L-Sadd=0; L-next=(busyMEM*)malloc(sizeof(busyMEM); L=L-next; L-fill=A; L-Eadd=51; L-Sadd=20; L-next=(busyMEM*)malloc(sizeof(busyMEM); L=L-next; L-fill=B; L-Eadd=71; L-Sadd=52; L-next=(busyMEM*)malloc(sizeof(busyMEM); L=L-next; L-fill
23、=C; L-Eadd=137; L-Sadd=98; L-next=(busyMEM*)malloc(sizeof(busyMEM); L=L-next; L-fill=D; L-Eadd=169; L-Sadd=148; L-next=p; resetfree();void Assign:resetfree() for(int i=0;inext!=p) if(L-next-Sadd-L-Eadd-1!=0) freeMEMi.length=L-next-Sadd-L-Eadd-1; freeMEMi.Sadd=L-Eadd+1; i+; L=L-next; freeMEMi.length=
24、256-L-Eadd-1; freeMEMi.Sadd=L-Eadd+1;void Assign:printList() coutendl; cout分区起始地址长度状态endl; int i=0; while(freeMEMi.length!=-1) if(freeMEMi.Sadd100) coutendl; cout freeMEMi.Saddk freeMEMi.lengthk空闲endl; else coutendl; cout freeMEMi.Saddk freeMEMi.lengthk空闲endl; i+; coutendl;void Assign:insert() busyMEM *L; L=(busyMEM*)malloc(sizeof(busyMEM); coutL-fill; couta; for(int i=0;i=a) break; if(i=19) coutnext-Eaddnext!=p) R=R-next; L-next=R-next; R-next=L; L-Sadd=freeMEMi.Sadd; L-Eadd=freeMEMi.Sadd+a-1; resetfree()
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1