1、操作系统实验报告学生学院 计算机学院 专业班级 2010级计算机科学与技术四班学 号 3110006015 学生姓名 张法光 指导教师 何翠红 2013 年 1 月 05 日0目录实验一、进程调度 4实验二、作业调度 8实验三、动态分区分配方式的模拟 15实验四、文件系统 2411 实验一 进程调度1、 实验目的编写并调试一个模拟的进程调度程序,采用“短进程优先”调度算法对五个进程进行调度。以加深对进程的概念及进程调度算法的理解 2、实验原理在多道程序系统中,一个作业被提交后必须经过处理机调度后,方能获得处理机执行。对调度的处理又都可采用不同的调度方式和调度算法。调度算法是指:根据系统的资源分
2、配策略所规定的资源分配算法。短进程优先调度算法是指对短进程优先调度的算法,它是从后备队列中选择一个或者若干个进程,将处理机分配给它,使它立即执行并一直执行到完成,或发生某事件而被阻塞放弃处理机时再重新调度。短进程优先调度源程序如下:#include#define n 5#define num 5#define max 65535typedef struct proint PRO_ID;/进程号int arrive_time;/到达时间int sum_time;/运行总时间int flag;Pro;/整数排序 int bubble(int temp)int i,j,tem=0;for(i=1;i
3、tempj+1)tem=tempj;tempj=tempj+1;tempj+1=tem;lastX=0;if(lastX=1) break;return temp0;/进程排序 Pro bubble(Pro p)int i,j;Pro temp=0;Pro snum;for(i=0;isj+1.sum_time)temp=sj;sj=sj+1;sj+1=temp;lastX=0;if(lastX=1) break;return s0;3void SPF(int p)if(n0)int i,j,k,l,tc=0;Pro seqn;Pro temp_seqn;printf(“*n“);printf
4、(“10 计科 4 班 张法光 3110006015n“); printf(“n“);printf(“实验一:短进程优先调度算法 SPFn“);printf(“请依次输入 5 个进程的进程号、到达时间和执行时间n“);printf(“成员变量用逗号隔开;进程间用回车隔开n“);printf(“*n“);for(i=0;i#include #include #define getpch(type) (type*)malloc(sizeof(type) #define null 0int n;float T1=0,T2=0;int times=0;struct jcb /作业控制块char nam
5、e10; /作业名int reachtime; /作业到达时间int starttime; /作业开始时间int needtime; /作业需要运行的时间float super; /作业的响应比int finishtime; /作业完成时间float cycletime; /作业周转时间float cltime; /作业带权周转时间char state; /作业状态struct jcb *next; /结构体指针*ready=NULL,*p,*q;typedef struct jcb JCB; void inital() /建立作业控制块队列,先将其排成先来先服务的模式队列int i;prin
6、tf(“n 输入作业数:“);scanf(“%d“,for(i=0;iname);getch();p-reachtime=i;printf(“作业默认到达时间:%d“,i);printf(“n 输入作业要运行的时间:“);scanf(“%d“,p-state=W;7p-next=NULL;if(ready=NULL) ready=q=p;elseq-next=p;q=p;void output(JCB* q,int j) /*显示所有作业的情况*/ JCB *pr=ready;float f=0.0;printf(“所有作业的情况: n“);/列表显示所有作业的情况if(j=3) printf
7、(“作业名tt 到达时间 t 所需运行间t 响应比tt 作业状态n“); printf(“%stt%dtt%dtt%ft%cn“, q-name,q-reachtime,q-needtime,q-super,q-state);while(pr) if(pr-supername,pr-reachtime,pr-needtime,f,pr-state);else printf(“%stt%dtt%dtt%ft%cn“, pr-name,pr-reachtime,pr-needtime,pr-super,pr-state); pr = pr-next;else printf(“作业名tt 到达时间
8、t 所需运行间t 作业状态n“);printf(“%stt%dtt%dtt%ctn“, q-name,q-reachtime,q-needtime,q-state);while(pr) printf(“%stt%dtt%dtt%ctn“, pr-name,pr-reachtime,pr-needtime,pr-state); pr = pr-next;void disp(JCB* q,int m) /显示作业运行后的周转时间及带权周转时间等if(m=3) /显示高响应比算法调度作业后的运行情况 output(q,m);printf(“n 作业%s 正在运行,估计其运行情况:n“,q-name)
9、;printf(“开始运行时刻t 完成时刻t 周转时间t 带权周转时间t 相应比nn“); printf(“%dtt%dtt%ft%ft%fn“,q-starttime,q-finishtime,q-cycletime,q-cltime,q-super);getch();else / 显示先来先服务 ,最短作业优先算法调度后作业的运行情况output(q,m);printf(“n 作业%s 正在运行,估计其运行情况:n“,q-name);8printf(“开始运行时刻t 完成时刻t 周转时间t 带权周转时间nn“);printf(“%dtt%dtt%ft%fn“,q-starttime,q-f
10、inishtime,q-cycletime,q-cltime);getch();void running(JCB *p,int m) /运行作业if(p=ready) /先将要运行的作业从队列中分离出来ready=p-next;p-next=NULL;elseq=ready;while(q-next!=p) q=q-next;q-next=p-next;p-starttime=times; /计算作业运行后的完成时间 ,周转时间等等p-state=R; p-finishtime=p-starttime+p-needtime; p-cycletime=(float)(p-finishtime-p
11、-reachtime); p-cltime=(float)(p-cycletime/p-needtime);T1+=p-cycletime;T2+=p-cltime;disp(p,m); /调用 disp()函数,显示作业运行情况times+=p-needtime;p-state=F;printf(“n 作业%s 已经完成!n 请输入任意键继续n“,p-name);free(p); /释放运行后的作业getch();void super() /计算队列中作业的高响应比JCB *padv;padv=ready;do if(padv-state=Wpadv=padv-next;while(padv
12、!=NULL);void final() /最后打印作业的平均周转时间,平均带权周转时间float s,t;9t=T1/n;s=T2/n;getch();printf(“nn 作业已经全部完成!“);printf(“n%d 个作业的平均周转时间是:%f“,n,t);printf(“n%d 个作业的平均带权周转时间是%f:nnn“,n,s);void hrn(int m) /高响应比算法JCB *min;int i,iden;system(“cls“);inital();for(i=0;istate=Wp=p-next;while(p!=NULL);running(min,m); /调用 run
13、ning()函数 /forfinal(); /调用 running()函数void fcfs(int m) /先来先服务算法int i,iden;system(“cls“);inital();for(i=0;istate=Wwhile(p!=NULLif(iden)i-;printf(“n 没有满足要求的进程 ,需等待“);times+;10if(times100)printf(“n 时间过长“);getch();elserunning(p,m); /调用 running()函数final(); /调用 running()函数void main() /主函数int m;while(1)prin
14、tf(“*“);printf(“nn 10 计科 4 班 张法光 3110006015n“);printf(“实验 2-作业调度系统n“); printf(“1.先来先服务算法n“);printf(“2.响应比高者优先算法n“);printf(“3.退出程序n“); printf(“*n“);printf(“选择所要操作:n“);scanf(“%d“,switch(m)case 1:fcfs(m);getch();times=0; main(); break;case 2:hrn(m);getch();times=0; main(); break;case 3:exit(0);default:
15、printf(“选择错误,重新选择.“);getch();system(“cls“);115、程序运行结果5.1 先来先服务算法125.2 响应比高者优先算法6、结果分析与实验小结参考了几个作业调度的范例,作业调度实践起来并不难,但需要慢慢调试。和同学讨论了设计思路之后就开始做了,虽然有小错误,但是经过反复调试也修正了 BUG。133 实验三 动态分区分配方式的模拟1、实验目的:了解动态分区分配方式中的数据结构和分配算法,并进一步加深对动态分区存储管理方式及其实现过程的理解2、实验内容:(1)用 C 语言分别实现采用首次适应算法和最佳适应算法的动态分区分配过程和回收过程。其中,空闲分区通过空闲
16、分区链(表)来管理;在进行内存分配时,系统优先使用空闲区低端的空间。(2)假设初始状态下,可用的内存空间为 640KB,并有下列的请求序列:作业 1 申请 130KB作业 2 申请 60KB作业 3 申请 100KB作业 2 释放 60KB作业 4 申请 200KB作业 3 释放 100KB作业 1 释放 130KB作业 5 申请 140KB作业 6 申请 60KB作业 7 申请 50KB作业 8 申请 60KB请分别采用首次适应算法和最佳适应算法进行内存的分配和回收,要求每次分配和回收后显示出空闲内存分区链的情况。3、思考:讨论各种分配算法的特点。(1)首次适应算法。使用该算法进行内存分配时
17、,从空闲分区链首开始查找,直至找到一个能满足其大小要求的空闲分区为止。然后再按照作业的大小,从该分区中划出一块内存分配给请求者,余下的空闲分区仍留在空闲分区链中。该算法倾向于使用内存中低地址部分的空闲分区,在高地址部分的空闲分区很少被利用,从而保留了高地址部分的大空闲区。显然为以后到达的大作业分配大的内存空间创造了条件。缺点在于低址部分不断被划分,留下许多难以利用、很小的空闲区,而每次查找又都从低址部分开始,这无疑会增加查找的开销。(2)最佳适应算法。该算法总是把既能满足要求,又是最小的空闲分区分配给作业。为了加速查找,该算法要求将所有的空闲区按其大小排序后,以递增顺序形成一个空白链。这样每次
18、找到的第一个满足要求的空闲区,必然是最优的。孤立地看,该算法似乎14是最优的,但事实上并不一定。因为每次分配后剩余的空间一定是最小的,在存储器中将留下许多难以利用的小空闲区。同时每次分配后必须重新排序,这也带来了一定的开销。4、源程序清单(需附详细的注释)#include#include#define Free 0 /空闲状态#define Busy 1 /已用状态#define OK 1 /完成#define ERROR 0 /出错#define MAX_length 640 /最大内存空间为 640KBtypedef int Status;typedef struct freearea/定
19、义一个空闲区说明表结构int ID; /分区号long size; /分区大小long address; /分区地址int state; /状态ElemType;/- 线性表的双向链表存储结构 -typedef struct DuLNode /double linked listElemType data; struct DuLNode *prior; /前趋指针struct DuLNode *next; /后继指针DuLNode,*DuLinkList;DuLinkList block_first; /头结点DuLinkList block_last; /尾结点Status alloc(in
20、t);/内存分配Status free(int); /内存回收Status First_fit(int,int);/首次适应算法Status Best_fit(int,int); /最佳适应算法void show();/查看分配Status Initblock();/开创空间表Status Initblock()/开创带头结点的内存空间链表15block_first=(DuLinkList)malloc(sizeof(DuLNode);block_last=(DuLinkList)malloc(sizeof(DuLNode);block_first-prior=NULL;block_first
21、-next=block_last;block_last-prior=block_first;block_last-next=NULL;block_last-data.address=0;block_last-data.size=MAX_length;block_last-data.ID=0;block_last-data.state=Free;return OK;/- 分 配 主 存 -Status alloc(int ch)int ID,request;coutID;coutrequest;if(requestdata.ID=ID; temp-data.size=request;temp-d
22、ata.state=Busy;DuLNode *p=block_first-next;while(p)if(p-data.state=Free p-data.ID=ID;return OK;break;if(p-data.state=Free temp-next=p; temp-data.address=p-data.address;p-prior-next=temp; p-prior=temp;p-data.address=temp-data.address+temp-data.size;p-data.size-=request;return OK;break;p=p-next;return
23、 ERROR;/- 最佳适应算法 -Status Best_fit(int ID,int request)int ch; /记录最小剩余空间DuLinkList temp=(DuLinkList)malloc(sizeof(DuLNode); temp-data.ID=ID; temp-data.size=request;temp-data.state=Busy;DuLNode *p=block_first-next;DuLNode *q=NULL; /记录最佳插入位置while(p) /初始化最小空间和最佳位置if(p-data.state=Free ch=p-data.size-reque
24、st;break;p=p-next;while(p)if(p-data.state=Free p-data.state=Busy;return OK;break;if(p-data.state=Free /更新剩余最小值q=p;/更新最佳位置指向p=p-next;if(q=NULL) return ERROR;/没有找到空闲块else/找到了最佳位置并实现分配temp-prior=q-prior;temp-next=q;temp-data.address=q-data.address;q-prior-next=temp;q-prior=temp;q-data.address+=request;
25、q-data.size=ch;return OK;/- 主 存 回 收 -Status free(int ID)18DuLNode *p=block_first;while(p)if(p-data.ID=ID)p-data.state=Free;p-data.ID=Free;if(p-prior-data.state=Free)/与前面的空闲块相连p-prior-data.size+=p-data.size;p-prior-next=p-next;p-next-prior=p-prior;if(p-next-data.state=Free)/与后面的空闲块相连p-data.size+=p-ne
26、xt-data.size;p-next-next-prior=p;p-next=p-next-next;break;p=p-next;return OK;/- 显示主存分配情况 -void show()coutnext;while(p)coutdata.ID=Free) coutdata.IDdata.addressdata.sizedata.state=Free) coutnext;/- 主 函 数-void main()int ch;/算法选择标记coutch;Initblock(); /开创空间表int choice; /操作选择标记while(1)coutchoice;if(choic
27、e=1) alloc(ch); / 分配内存else if(choice=2) / 内存回收int ID;coutID;free(ID);else if(choice=3) show();/显示主存else if(choice=0) break; /退出else /输入操作有误cout#include#include#define NULL 0#define getpch(type,num) (type*)malloc(sizeof(type)*num)struct ufd /* 第二级:用户文件目录 UFD */char filename10; /* 文件名 */ char procode3
28、; /* 保护码 1:读 2:写 3:执行*/int length; /* 文件长度 */*p;typedef struct ufd UFD;struct mdf /* 第一级:主目录 MDF */char name10; /* 用户名 */UFD* directory; /* 文件目录指针 */maindir10; /* 用户数组 */typedef struct mdf MDF;struct afd /* 文件运行目录 */char filename10; /* 文件名 */ char procode3; /* 保护码 1:读 2:写 3:执行*/int rw; /* 读写指针 初始状态读
29、:0 写: 文件长度 */afd5;int usernum,opennum; /* 登陆用户数量 打开文件数量 */ int filenum10; /* 所有的用户目录下的文件数目 */char username10; /* 当前登陆系统的用户名*/char command10=“create“,“delete“,“open“,“close“,“read“,“write“,“display“,“quit“; /*文件操作命令*/void login() /*用户注册,信息写入 database 文件*/int i,j;FILE *fp; int loginum;int creatnum10;p
30、rintf(“tt=注册页面=nn“);24printf(“tt 请输入注册的用户数量 :“);scanf(“%d“,for(i=0;i=10)/*如果用户的文件已有 10 个*/printf(“ntt 用户的文件数量已达到上限,即 10 个!n“);return ;26printf(“tt=新建文件页面=nn“);printf(“tt 请输入要建立的文件名 :“);scanf(“%s“,cfilename);for(i=0;ifilename,cfilename)=0)printf(“tt 文件名 %s 已存在!n“,cfilename);system(“pause“);system(“cl
31、s“);return ;printf(“tt 请输入要建立的文件的属性 (1:读 2:写 3:执行):“);scanf(“%s“,code);printf(“tt 请输入要建立的文件的长度 :“);scanf(“%d“,strcpy(pfilenumuserid.filename,cfilename); /*添加新文件名*/strcpy(pfilenumuserid.procode,code); /*添加保护码*/pfilenumuserid.length=filelen; /*添加文件长度*/filenumuserid=filenumuserid+1; /*更新文件数量*/printf(“t
32、t=文件建立成功!=n“,cfilename);system(“pause“);system(“cls“);void deletefile(int userid) /*删除文件*/system(“cls“);char dfilename10;int i,j;printf(“tt=删除文件页面=nn“);printf(“tt 请输入要删除的文件名 :“);scanf(“%s“,dfilename);for(i=0;i=5)printf(“tt 打开超过 5 个文件!n“);return ;printf(“tt 请输入要打开的文件的文件名 :“);scanf(“%s“,ofilename);for(i=0;iopennum;i+)if(strcmp(afdi.filename,ofilename)=0) /*文件已经打开*/printf(“tt 文件 %s 已打开!n“,ofilename);return ;for(i=0;ifilenumuserid;i+) /*在运行文件目录中找到要打