计算机操作系统实训报告_第1页
计算机操作系统实训报告_第2页
计算机操作系统实训报告_第3页
计算机操作系统实训报告_第4页
计算机操作系统实训报告_第5页
已阅读5页,还剩30页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

PAGE1目录任务一2任务二4任务三13任务四19任务五25实训总结36任务一

分析操作系统所面临的操作需求【实训目的】让学生可以更好的理解、掌握和应用操作系统中的进程管理、存储管理、设备管理和文件管理等功能。【实训内容】1.熟悉实训环境;2.分析操作系统的操作需求;3.资料搜集与整理,进行实训的前期准备。【实训步骤】1.分析与设计图1-1实训总体结构图【思考题】1.

操作系统中各模块有怎样的功能?答:进程管理模块用于分配和控制处理机;设备管理模块主要负责对I/O设备的分配与操纵;文件管理模块主要负责文件的存取、共享和保护;存储管理模块主要负责的分配与回收。2.

它们之间有怎样的联系?答:设备管理、文件管理和储存管理都需要进程的管理;文件需要文件管理进行存储,同时也需要储存管理来对文件存储分配空间等等。3.

针对某一特定的应用环境,如何完善操作系统的功能?答:要想完善操作系统的功能,必须要合理安排各个功能模块,并利用有效的算法对各个功能进行管理和处理。任务二进程管理【实训目的】掌握临界区的概念及临界区的设计原则;掌握信号量的概念、PV操作的含义以及应用PV操作实现进程的同步与互斥;分析进程争用资源的现象,学习解决进程互斥的方法;掌握进程的状态及状态转换;掌握常用的进程调度算法。【实训内容】1.分析进程的同步与互斥现象,编程实现经典的进程同步问题——生产者消费者问题的模拟;2.编写允许进程并行执行的进程调度程序,在常用的进程(作业)调度算法:先来先服务算法、短作业优先算法、最高响应比优先算法、高优先权优先算法等调度算法中选择一种调度算法进行简单模拟,并输出平均周转时间和平均带权周转时间。【实训步骤】一.生产者与消费者问题1.分析与设计创建生产者线程创建生产者线程创建消费者线程缓冲区输入数据判断生产者是否阻塞生产者等待,消费者从缓冲区取出数据是否判断缓冲区是否为空是消费者阻塞,等待生产者生产产品后被唤醒否图2-1生产者与消费者问题分析图2.程序代码#include<windows.h>#include<iostream>constunsignedshortBUFFER=5;//缓冲区长度unsignedshortProductID=0;//产品号unsignedshortConsumeID=0;//将被消耗的产品号unsignedshortin=0;//产品进缓冲区时的缓冲区产品个数unsignedshortout=0;//产品出缓冲区时的缓冲区产品个数intg_buffer[BUFFER];//缓冲区为循环队列boolg_continue=true;//控制程序结束HANDLEg_hMutex;//线程间互斥对像HANDLEg_hFullSemaphore;//满则生产者等待HANDLEg_hEmptySemaphore;//空则消费者等待DWORDWINAPIProducer(LPVOID);//生产者线程DWORDWINAPIConsumer(LPVOID);//消费者线程//主程序intmain(){//创建各个互斥信号 g_hMutex=CreateMutex(NULL,FALSE,NULL); g_hFullSemaphore=CreateSemaphore(NULL,BUFFER-1,BUFFER-1,NULL); g_hEmptySemaphore=CreateSemaphore(NULL,0,BUFFER-1,NULL); constunsignedshortPRODUCERS_COUNT=2;//生产者的个数 constunsignedshortCONSUMERS_COUNT=1;//消费者的个数//总的线程数 constunsignedshortTHREADS_COUNT=PRODUCERS_COUNT+CONSUMERS_COUNT; HANDLEhThreads[PRODUCERS_COUNT];//各线程的handle DWORDproducerID[CONSUMERS_COUNT];//生产者线程的标识符 DWORDconsumerID[THREADS_COUNT];//消费者线程的标识符//创建生产者线程 for(inti=0;i<PRODUCERS_COUNT;++i) { hThreads[i]=CreateThread(NULL,0,Producer,NULL,0,&producerID[i]); if(hThreads[i]==NULL) return-1; }//创建消费者线程 for(i=0;i<CONSUMERS_COUNT;++i) { hThreads[PRODUCERS_COUNT+i]=CreateThread(NULL,0,Consumer,NULL,0,&consumerID[i]); if(hThreads[i]==NULL) return-1; } while(g_continue) { if(getchar()) { g_continue=false;//按回车后终止程序运行 } } return0;}//生产一个产品,把新生产的产品放入缓冲区voidProduce(){ std::cerr<<"生产产品"<<++ProductID<<std::endl; std::cerr<<"将新的产品"; g_buffer[in]=ProductID; in=(in+1)%BUFFER; std::cerr<<"放入缓冲区"<<std::endl;//输出缓冲区当前的状态 for(inti=0;i<BUFFER;++i) { std::cout<<i<<":"<<g_buffer[i]; if(i==in)std::cout<<"←生产"; if(i==out)std::cout<<"←消费"; std::cout<<std::endl; }}//从缓冲区中取出一个产品,并将其消耗voidConsume(){ std::cerr<<"从缓冲区中取出产品"; ConsumeID=g_buffer[out]; out=(out+1)%BUFFER; std::cout<<std::endl; //输出缓冲区当前的状态 for(inti=0;i<BUFFER;++i) { std::cout<<i<<":"<<g_buffer[i]; if(i==in)std::cout<<"←生产"; if(i==out)std::cout<<"←消费"; std::cout<<std::endl; } std::cerr<<"消耗一个产品"<<ConsumeID<<std::endl;}//生产者DWORDWINAPIProducer(LPVOIDlpPara){ while(g_continue) { WaitForSingleObject(g_hFullSemaphore,INFINITE); WaitForSingleObject(g_hMutex,INFINITE); Produce(); Sleep(1500);//此处以毫秒为单位 ReleaseMutex(g_hMutex); ReleaseSemaphore(g_hEmptySemaphore,1,NULL); } return0;}//消费者DWORDWINAPIConsumer(LPVOIDlpPara){ while(g_continue) { WaitForSingleObject(g_hEmptySemaphore,INFINITE); WaitForSingleObject(g_hMutex,INFINITE); Consume(); Sleep(1500);//此处以毫秒为单位 ReleaseMutex(g_hMutex); ReleaseSemaphore(g_hFullSemaphore,1,NULL); } return0;}3.程序运行截图图2-2生产者与消费者问题运行截图二.先来先服务算法1.分析与设计初始化pcb,输入进程信息初始化pcb,输入进程信息各进程按先来先到的顺序进入就绪队列运行运行进程所需CPU时间撤消该进程判断就绪队列是否为空否开始是退出图2-3先来先服务算法设计图2.程序代码#include<stdio.h>//定义进程的结构体structfcfs{ charname[10];//进程名称 intpriority;//进程优先数 floatarrivetime;//到达时间 floatservicetime;//运行时间 floatstarttime;//开始时间 floatfinishtime;//完成时间 floatreturntime;//周转时间 floatwreturntime;//带权周转时间};fcfsa[50];//程序的输入显示及提示voidinput(fcfs*p,intN){ inti; printf("请依次输入进程名称→到达时间→运行时间→进程优先数:\n"); for(i=0;i<=N-1;i++) { printf("\n输入%d号进程信息:\n",i+1); scanf("%s%f%f%d",&p[i].name,&p[i].arrivetime,&p[i].servicetime,&p[i].priority); }}//程序的输出显示voidPrint(fcfs*p,floatarrivetime,floatservicetime,floatstarttime,floatfinishtime,floatreturntime,floatwreturntime,intpriority,intN){ intk; printf("运行指令:"); printf("%s",p[0].name); for(k=1;k<N;k++) { printf("→%s",p[k].name); } printf("\n进程信息:\n"); printf("\n进程\t到达\t运行\t开始\t结束\t周转\t带权周转进程优先数\n"); for(k=0;k<=N-1;k++) { printf("%s\t%-.2f\t%-.2f\t%-.2f\t%-.2f\t%-.2f\t%-.2f\t\t%d\n",p[k].name,p[k].arrivetime,p[k].servicetime,p[k].starttime,p[k].finishtime,p[k].returntime,p[k].wreturntime,p[k].priority); }}//排序采用冒泡排序法进行排序,排序顺序从小到大voidsort(fcfs*p,intN){ for(inti=0;i<=N-1;i++) for(intj=0;j<=i;j++) if(p[i].arrivetime<p[j].arrivetime) { fcfstemp; temp=p[i]; p[i]=p[j]; p[j]=temp; }}//运行阶段voidfunciton(fcfs*p,floatarrivetime,floatservicetime,floatstarttime,floatfinishtime,float&returntime,float&wreturntime,intpriority,intN){ intk; for(k=0;k<=N-1;k++) { if(p[k].arrivetime>p[k-1].finishtime) { p[k].starttime=p[k].arrivetime; p[k].finishtime=p[k].arrivetime+p[k].servicetime; } else { p[k].starttime=p[k-1].finishtime; p[k].finishtime=p[k-1].finishtime+p[k].servicetime; } } for(k=0;k<=N-1;k++) { p[k].returntime=p[k].finishtime-p[k].arrivetime; p[k].wreturntime=p[k].returntime/p[k].servicetime; }}//模拟操作系统的先来先服务算法voidFCFS(fcfs*p,intN){ floatarrivetime=0,servicetime=0,starttime=0,finishtime=0,returntime=0,wreturntime=0,priority=0; sort(p,N); funciton(p,arrivetime,servicetime,starttime,finishtime,returntime,wreturntime,priority,N); Print(p,arrivetime,servicetime,starttime,finishtime,returntime,wreturntime,priority,N);}//主函数voidmain(){ intN; printf("\t\t\t进程调度之先来先服务调度算法\n"); printf("请输入进程数:\n"); scanf("%d",&N); input(a,N); FCFS(a,N);}3.程序运行截图图2-4先来先服务调度算法运行截图【思考题】1.针对某一具体应用环境,如何选择合适的调度算法?答:应根据具体情况来选用合适的调度算法。比如,在批处理系统中,为了照顾为数众多的短作业,应采用短作业优先调度的调度算法;在分时系统中,为了保证系统具有合理的响应时间,应采用轮转法进行调度。非抢占式调度算法,有利于长作业,不利于短作业。任务三存储管理【实训目的】掌握物理内存和虚拟内存的基本概念;掌握重定位的基本概念及其要点,理解逻辑地址与绝对地址;掌握各种存储管理的实现方法,包括基本原理、地址变换和缺页中断、主存空间的分配及分配算法;掌握常用淘汰算法。【实训内容】编写一个模拟的动态页式存储管理程序,实现对动态页式存储的淘汰算法的模拟(在先进先出淘汰算法、最近最少使用淘汰算法、最不经常使用淘汰算法三种算法中选择一种进行模拟)并计算各个算法的缺页率;并且页面淘汰算法在淘汰一页时,只将该页在页表中抹去,而不再判断它是否被改写过,也不将它写回到辅存【实训步骤】分析与设计设置一个后进先出栈,栈大小为分配给这个进程的页面数。在在系统中设定一个计数器,进程进程进行访问内页面操作都把计数器的值加1,把结果值赋值给访问的页面,在淘汰页面时选择计数器值最小的页面淘汰。这样的栈顶上总是保存着最近被访问的页面号,而栈底保存的就是最近最久没有被访问的页面号。如图3-1所示开始开始是否还有指令计算出页号在实存堆栈中查找该页号是否找到新页块压入栈顶,同时栈底页号移出计算出命中率结束将新页放在栈顶,同时向下移动其余页号是否否是图3-1最近最久未使用置换算法分析图程序代码#include<stdio.h>#include<stdlib.h>//最近最久未使用置换算法//参数说明:p地址流,n地址流的个数,pageSize页面大小,pageTable页表,count页表大小voidLRU(intp[],intn,intpageSize,intpageTable[],intcount){ inti,pageNo,j,pagecount,k; floatsum; int*stack=(int*)malloc(sizeof(int)*count); pagecount=0; k=0; sum=0; system("cls"); printf("\n\n\t\t\t存储管理最近最少使用淘汰算法\n\n"); for(i=0;i<n;i++) { pageNo=p[i]/pageSize; printf("\t\t调入页号%d后\t",pageNo); printf("\t\t页表:"); for(j=0;j<pagecount;j++)//判断页号是否在页表中 { if(pageNo==pageTable[j])//如果页号在页表中 { for(k=0;k<count;k++)//设置栈中各页面使用情况 { if(stack[k]==pageNo) { if(k!=count-1) { for(;k<count-1;k++) { stack[k]=stack[k+1]; } stack[k]=pageNo; } } } break; } } //页号不在页表中,插入页表 if(j==pagecount) { //如果页表不满 if(pagecount<count) { pageTable[pagecount++]=pageNo; stack[pagecount-1]=pageNo; } //如果页表已满 else { for(j=0;j<count;j++) { if(pageTable[j]==stack[0]) { pageTable[j]=pageNo; for(k=0;k<count-1;k++)//设置栈中各页面使用情况 { stack[k]=stack[k+1]; } stack[k]=pageNo; break; } } } sum++;//缺页数 } //打印页表 for(j=0;j<count;j++) { if(pageTable[j]>=0) { printf("%d",pageTable[j]); } } printf("\n"); } sum/=n; sum*=100; printf("\t\t\t缺页率:%.1f%%\n\n",sum); free(stack);}voidmain(){ intn,pageSize=1024,pageTable[3]; int*p,i; FILE*fp; system("cls"); printf("\n\n\t\t\t存储管理最近最少使用淘汰算法\n\n\n"); printf("请确认在\"Address.txt\"文件中已输入地址流.\n"); printf("如果没有,请自行新建后再运行.\n\n\n\n"); system("pause"); if((fp=fopen("Address.txt","r+"))==NULL) { printf("打开文件出错!\n"); system("pause"); return; } fscanf(fp,"%d",&n); p=(int*)malloc(sizeof(int)*n); printf("\n\n\n读取到以下的地址流:\n"); for(i=0;i<n;i++) { fscanf(fp,"%d",&p[i]); printf("%d",p[i]); } printf("\n\n"); fclose(fp); system("pause"); system("cls");LRU(p,n,pageSize,pageTable,3);}3.程序运行截图图3-2最近最久未使用置换算法程序截图图3-3最近最久未使用置换算法程序截图【思考题】1.各种不同的页面淘汰算法有哪些优缺点?为什么会产生页面抖动?什么是belady现象?这种现象该如何避免?答:最佳值换算法其所选择的被淘汰页将是以后用不适用的,或许是在最长(未来)时间内不再被访问的页面。采用最佳值换算法通常可保证获得最低的缺页率。但是由于人们目前还无法预知一个进程在内存的若干个页面中,哪一个页面是未来最长时间内不再被访问的,因此该算法是无法实现的,但可以利用该算法去评价其它算法。先进先出置换算法(FIFO)是最直观的算法,由于它可能是性能最差的算法,故实际应用极少。最近最久未使用置换算法(LRU)虽然是一种比较好的算法,但要求系统有较多的支持硬件。因为刚被淘汰出去的页,过后不久又要访问它,需要再次调入,而调入后不久又再次被淘汰,然后又要访问,如此反复,使得系统的把大部分时间用在页面的调进调出上,这种形象称为“抖动”。随着物理块数的增多缺页率增大,从而造成Belady异常现象。尽量避免物理块数不断增多缺页率最大。任务四设备管理【实训目的】掌握独占设备的使用方式,以及设备的分配和回收;掌握用死锁避免方法来处理申请独占设备可能带来死锁。【实训内容】用死锁避免方法来处理申请独占设备可能造成的死锁,程序实现对银行家算发的模拟。【实训步骤】分析与设计1.1、银行家算法:设进程x提出请求Request[y],则银行家算法按如下规则进行判断。(1)如果Request[y]>Need[x,y],则报错返回。(2)如果Request[y]>Available,则进程i进入等待资源状态,返回。(3)假设进程n的申请已获批准,于是修改系统状态:Available=Available-RequestAllocation=Allocation+RequestNeed=Need-Request(4)系统执行安全性检查,如安全,则分配成立;否则试探险性分配作废,系统恢复原状,进程等待。1.2、安全性检查:(1)设置两个工作向量Work=Available;Finish[z]=False(2)从进程集合中找到一个满足下述条件的进程,Finish[x]=FalseNeed<=Work如找到,执行(3);否则,执行(4)(3)设进程获得资源,可顺利执行,直至完成,从而释放资源。Work=Work+AllocationFinish=TrueGOTO2(4)如所有的进程Finish[z]=true,则表示安全;否则系统不安全1.3银行家算法实现流程图,如图4-1所示。进程P进程Px发出请求向量RequestxRequestx≤Needx试探分配修改相关数据向量是否安全同意分配请求正式分配返回错误Px请求被拒绝试探分配作废恢复各矩阵Px需等待是否是否是否Requestx≤Available图4-1银行家算法实现流程图程序代码#include<string.h>#include<stdio.h>#include<stdlib.h>#defineX5//总进程数#defineY3//总资源数//银行家算法定义结构体structbanker{intmax[X][Y];//最大需求矩阵intallocation[X][Y];//分配矩阵intneed[X][Y];//需求矩阵 intavailable[Y];//可利用资源向量};//初始化voidinitilize(banker&x){ inti,j; printf("请输入数据(系统设定总进程数为5,总资源数为3):\n");printf("最大需求矩阵:\n"); for(i=0;i<X;i++)//设置最大需求矩阵 { for(j=0;j<Y;j++) { scanf("%d",&x.max[i][j]); } } printf("分配矩阵:\n"); for(i=0;i<X;i++)//设置分配矩阵 { for(j=0;j<Y;j++) { scanf("%d",&x.allocation[i][j]); } } for(i=0;i<X;i++)//设置需求矩阵 { for(j=0;j<Y;j++) { x.need[i][j]=x.max[i][j]-x.allocation[i][j]; } } printf("可利用资源向量:\n"); for(i=0;i<Y;i++)//设置可利用资源向量 { scanf("%d",&x.available[i]); }}//检查安全性intsafe(bankerx){ inti,j; intsafeprocess[X];//安全序列向量 intwork[Y];//空闲资源矩阵 intFinish[X];//进程完成标志矩阵 for(i=0;i<Y;i++)//开始时可利用资源向量就是空闲资源矩阵 work[i]=x.available[i];for(i=0;i<X;i++)//初始化标志矩阵为false Finish[i]=false; intk=0;//安全序列排列号 for(i=0;i<X;i++)//每次都从第一个进程开始做循环 { if(Finish[i]==false) { for(j=0;j<Y;j++) { if(x.need[i][j]>work[j])//判断当前进程需求矩阵能否得到满足 break;//不满足则跳出 } if(j==Y)//第i个进程满足执行条件 { safeprocess[k++]=i;//将进程号存入安全序列向量 for(intq=0;q<Y;q++)//修改空闲资源矩阵 work[q]+=x.allocation[i][q]; Finish[i]=true;//标志该进程可完成 i=-1;//下次检查从第一个进程重新查起 } } } for(i=0;i<X;i++)//检查标志数组,若有一个为false则找不到安全序列 if(!Finish[i]) { printf("无法找到安全序列,系统处于不安全状态!\n"); return0; } printf("安全序列为:");//找到安全序列并显示该序列 for(i=0;i<X;i++) printf("%d号进程",safeprocess[i]+1); printf("\n"); return1;}//系统对进程资源申请的处理voidallocate(banker&x){ bankertemp=x;//临时变量存储x的初值 intRequest[Y];//请求向量 intnumber;//进程号 inti; printf("请输入要申请资源的进程序号:\n"); scanf("%d",&number); printf("请输入请求向量:\n"); for(i=0;i<Y;i++) scanf("%d",&Request[i]);//输入请求向量for(i=0;i<Y;i++) { if(Request[i]>x.need[number-1][i])//所需资源数大于需求量 { printf("错误!进程所需要的资源数已超过最大值。\n"); return; } if(Request[i]>x.available[i])//所需资源数大于可利用资源 { printf("错误!系统中没有足够的资源满足进程的申请。\n"); return; } } for(i=0;i<Y;i++)//假设系统将申请资源数分配给该进程,对数据进行相关修改 { x.available[i]-=Request[i]; x.need[number-1][i]-=Request[i]; x.allocation[number-1][i]+=Request[i]; } if(safe(x))//安全性检查结果为安全 { printf("系统可以为该进程分配资源.\n"); return; } else//安全性检查结果为不安全 { printf("系统不为该进程分配资源\n"); x=temp;//将相关矩阵修改过来,表示资源不分配资源 return; }}//主程序voidmain(void){ bankercurrent;//定义变量initilize(current);//初始化safe(current);//检查安全性 while(1)//循环执行进程申请资源和系统对申请的处理 { allocate(current);}}运行并测试程序,并给出程序运行界面。图4-2银行家算法运行截图【思考题】1.如果产生了死锁,应如何解除?答:当发现有死锁时,便应立即把它们从死锁状态中解脱出来。常采用解除死锁的两种方法是:剥夺资源。从其它进程剥夺足够数量的资源给死锁进程,以解除死锁状态。撤销进程。最简单的撤销进程的方法是使全部死锁状态进程都夭折掉;稍微温和一点的方法是按照某种顺序逐个的撤销进程,直至有足够的资源可用,使死锁状态消除为止。任务五文件管理【实训目的】掌握文件的存取方法;掌握文件的逻辑结构和物理结构;掌握存储空间的分配和回收;掌握磁盘管理与调度。【实训内容】用程序模拟磁盘的调度过程,并计算各磁盘调度算法包括先来先服务算法、最短寻道时间优先算法、扫描算法和循环扫描算法的平均寻道长度。【实训步骤】分析与设计输入当前磁道号now输入当前磁道号now磁头移动距离sum=abs(now-array[0])磁头移动总距离Sum+=abs(array[j]-array[i])输出磁盘调度序列array[j]目前的位置变为当前的位置j++j<m输出平均寻道长度avg=sum/(m)图5-1先来先服务算法流程图将磁道号从小到大排序将磁道号从小到大排序输入当前磁道号nowarray[m-1]≤now输出磁盘调度序列array[j]目前的位置变为当前的位置now=array[i]磁头移动总距离sum=now-array[i]I≥0输出磁盘调度序列array[j](array[0]≥now磁头移动总距离sum=now-array[i]目前的位置变为当前的位置now=array[i]now=array[i]i<m确定当前磁道在已排的序列中的位置now-array[l])≤(array[r]-now先向磁道号减小方向访问,再向磁道号增加方向访问输出磁盘调度序列先向磁道号增加方向访问,再向磁道号减小方向访问输出磁盘调度序列输出平均寻道长度avg=sum/(m)图5-2最短寻道时间算法流程图将磁道号从小到大排序将磁道号从小到大排序输入当前磁道号now,移动臂的移动的方向array[m-1]<=now磁头移动总距离sum=now-array[i]输出磁盘调度序列array[j]i>=0(array[0]>=now输出磁盘调度序列array[j]i<m磁头移动总距离sum=array[i]-now确定当前磁道在已排的序列中的位置switch(d)case0:移动臂向磁道号减小方向访问case1:移动臂向磁道号增加方向访问访问输出磁盘调度序列输出磁盘调度序列输出平均寻道长度avg=sum/(m)图5-3扫描算法流程图程序代码#include"stdio.h"#include"stdlib.h"intNAll=0;intBest[5][2];//用作寻道长度由低到高排序时存放的数组intLimit=0;//输入寻找的范围磁道数iintJage;floatAver=0;//数组Sour复制到数组Dist,复制到x个数voidCopyL(intSour[],intDist[],intx){ inti; for(i=0;i<=x;i++) { Dist[i]=Sour[i]; }}//打印输出数组voidPrint(intPri[],intx){ inti; for(i=0;i<=x;i++) { printf("%5d",Pri[i]); }}//随机生成磁道数voidSetDI(intDiscL[]){ inti; for(i=0;i<=9;i++) { DiscL[i]=rand()%Limit;//随机生成10个磁道号 } system("cls"); printf("\n\n\n需要寻找的磁道号:"); Print(DiscL,9);//输出随机生成的磁道号 printf("\n");}//数组Sour把x位置的数删除,并把y前面的数向前移动voidDelInq(intSour[],intx,inty){ inti; for(i=x;i<y;i++) { Sour[i]=Sour[i+1]; x++; }}//先来先服务算法(FCFS)voidFCFS(intHan,intDiscL[]){ intRLine[10];//将随机生成的磁道数数组Discl[]复制给数组RLine[] inti,k,All,Temp;//Temp是计算移动的磁道距离的临时变量 All=0;//统计全部的磁道数变量 k=9;//限定10个的磁道数 CopyL(DiscL,RLine,9);//复制磁道号到临时数组RLine printf("\n按照FCFS算法磁道的访问顺序为:"); All=Han-RLine[0]; for(i=0;i<=9;i++) {Temp=RLine[0]-RLine[1];//求出移动磁道数,前一个磁道数减去后一个磁道数得出临时的移动距离 if(Temp<0) Temp=(-Temp);//移动磁道数为负数时,算出相反数作为移动磁道数 printf("%5d",RLine[0]); All=Temp+All;//求全部磁道数的总和 DelInq(RLine,0,k);//每个磁道数向前移动一位 k--; } Best[Jage][1]=All;//Best[][1]存放移动磁道数 Best[Jage][0]=1;//Best[][0]存放算法的序号为:1 Jage++;//排序的序号加1 Aver=((float)All)/10;//求平均寻道次数 printf("\n移动磁道数:<%5d>",All); printf("\n平均寻道长度:*%0.2f*",Aver);}//最短寻道时间优先算法(SSTF)voidSSTF(intHan,intDiscL[]){ inti,j,k,h,All; intTemp;//Temp是计算移动的磁道距离的临时变量 intRLine[10];//将随机生成的磁道数数组Discl[]复制给数组RLine[] intMin; All=0;//统计全部的磁道数变量 k=9;//限定10个的磁道数 CopyL(DiscL,RLine,9);//复制磁道号到临时数组RLine printf("\n按照SSTF算法磁道的访问顺序为:"); for(i=0;i<=9;i++) { Min=64000; for(j=0;j<=k;j++)//内循环寻找与当前磁道号最短寻道的时间的磁道号 { if(RLine[j]>Han)//如果第一个随机生成的磁道号大于当前的磁道号,执行下一句 Temp=RLine[j]-Han;//求出临时的移动距离 else Temp=Han-RLine[j];//求出临时的移动距离 if(Temp<Min)//如果每求出一次的移动距离小于Min,执行下一句 { Min=Temp;//Temp临时值赋予Min h=j;//把最近当前磁道号的数组下标赋予h } } All=All+Min;//统计一共移动的距离 printf("%5d",RLine[h]); Han=RLine[h]; DelInq(RLine,h,k);//每个磁道数向前移动一位 k--; } Best[Jage][1]=All;//Best[][1]存放移动磁道数 Best[Jage][0]=2;//Best[][0]存放算法的序号为:2 Jage++;//排序序号加1 Aver=((float)All)/10;//求平均寻道次数 printf("\n移动磁道数:<%5d>",All); printf("\n平均寻道长度:*%0.2f*",Aver);}//扫描算法(SCAN)intSCAN(intHan,intDiscL[],intx,inty){ intj,n,k,h,m,All; intt=0; intTemp; intMin; intRLine[10];//将随机生成的磁道数数组Discl[]复制给数组RLine[] intOrder; Order=1; k=y; m=2;//控制while语句的执行,即是一定要使当前磁道向内向外都要扫描到 All=0;//统计全部的磁道数变量 CopyL(DiscL,RLine,9);//复制磁道号到临时数组RLine printf("\n按照SCAN算法磁道的访问顺序为:"); Min=64000; for(j=x;j<=y;j++)//寻找与当前磁道号最短寻道的时间的磁道号 { if(RLine[j]>Han)//如果第一个随机生成的磁道号大于当前的磁道号,执行下一句 Temp=RLine[j]-Han;//求出临时的移动距离 else Temp=Han-RLine[j];//求出临时的移动距离 if(Temp<Min) { Min=Temp;//Temp临时值赋予Min h=j;//把最近当前磁道号的数组下标赋予h } } All=All+Min; printf("%5d",RLine[h]); if(RLine[h]>=Han){//判断磁道的移动方向,即是由里向外还是由外向里 Order=0; t=1; } Han=RLine[h]; DelInq(RLine,h,k);//每个磁道数向前移动一位 k--; while(m>0) { if(Order==1)//order是判断磁盘扫描的方向标签,order是1的话,磁道向内移动 { for(j=x;j<=y;j++) { h=-1; Min=64000; for(n=x;n<=k;n++)//判断离当前磁道最近的磁道号 { if(RLine[n]<=Han) { Temp=Han-RLine[n]; if(Temp<Min) { Min=Temp;//Temp临时值赋予Min h=n;//把最近当前磁道号的数组下标赋予h } } } if(h!=-1) { All=All+Min;//叠加移动距离 printf("%5d",RLine[h]); Han=RLine[h];//最近的磁道号作为当前磁道 DelInq(RLine,h,k); k--; } } Order=0;//当完成向内的移动,order赋予0,执行else语句,使磁道向外移动 m--;//向内完成一次,m减一次,保证while循环执行两次 } else//order是0的话,磁道向外移动 { for(j=x;j<=y;j++) { h=-1; Min=64000; for(n=x;n<=k;n++)//判断离当前磁道最近的磁道号 { if(RLine[n]>=Han) { Temp=RLine[n]-Han; if(Temp<Min) { Min=Temp;//Temp临时值赋予Min h=n;//把最近当前磁道号的数组下标赋予h } } } if(h!=-1) { All=All+Min;//叠加移动距离 printf("%5d",RLine[h]); Han=RLine[h];//最近的磁道号作为当前磁道 DelInq(RLine,h,k); k--; } } Order=1;//当完成向内的移动,order赋予0,执行else语句,使磁道向外移动 m--;//向内完成一次,m减一次,保证while循环执行两次 } } NAll=NAll+All; if((y-x)>5) { Best[Jage][1]=All;//Best[][1]存放移动磁道数 Best[Jage][0]=3;//Best[][0]存放算法的序号为:3 Jage++;//排序序号加1 Aver=((float)All)/10;//求平均寻道次数 printf("\n移动磁道数:<%5d>",All); printf("\n平均寻道长度:*%0.2f*",Aver); } if(t==1)printf("\n磁道由内向外移动"); elseprintf("\n磁道由外向内移动"); return(Han);}//寻道长度由低到高排序voidSort(){ inti,j,Temp; for(i=0;i<5;i++) { for(j=0;j<4;j++) { if(Best[j][1]>Best[j+1][1])//如果前一个算法的移动磁道距离大于后一个移动磁道数,执行下面语句 { Temp=Best[j+1][1];//从这起下三行执行冒泡法将移动距离大小排序,排完后则执行每个算法的排序 Best[j+1][1]=Best[j][1]; Best[j][1]=Temp; Temp=Best[j+1][0];//将每个算法的序号用冒泡法排序 Best[j+1][0]=Best[j][0]; Best[j][0]=Temp; } } }}voidmain(){ inti; intDiscLine[10];//声明准备要生成的随机磁道号的数组 intHand;//磁道数 intCon=1; intn; while(Con==1) { Jage=0; system("cls"); printf("\n\n\t取值范围是0-65536:"); printf("\n\n\t请输入初始的磁道数:"); scanf("%d",&Hand); printf("\n\t请输入寻找的范围:"); scanf("%d",&Limit); if(Limit>65536||Hand>65536) { printf("超出范围!"); } else{ system("cls"); printf("\n\n\n\n\n"); printf("\t************************主菜单***************************\n"); printf("\t****\n"); printf("\t**1.先来先服务算

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论