操作系统实验指导书_第1页
操作系统实验指导书_第2页
操作系统实验指导书_第3页
操作系统实验指导书_第4页
操作系统实验指导书_第5页
已阅读5页,还剩78页未读 继续免费阅读

下载本文档

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

文档简介

年4月19日操作系统实验指导书文档仅供参考《操作系统》实验指导书绍兴文理学院计算机系

前言1.实验总体目标经过学生自己动手设计实验验证理论知识,使学生掌握操作系统特征和功能,掌握不同调度算法下进程的调度、进程控制、进程调度与死锁,并必须掌握作业管理、存储器管理、设备管理和文件管理的主要原理。加深对操作系统基本原理理解。⒉适用专业计算机科学与技术⒊先修课程C语言程序设计、计算机组成原理、数据结构⒋实验课时分配序号实验名称学时实验要求实验类型1分析操作系统所面临的操作需求2必修验证2进程管理4必修设计3存储管理4必修设计4设备管理2必修设计5文件管理4必修设计⒌实验环境有70台中等配置的计算机组成的小型局域网的实验室环境。计算机的具体要求:(1)Pentium133Hz以上的CPU;(2)建议至少256MB的内存;(3)建议硬盘至少2GB,并有1GB空闲空间。(4)安装Windows操作系统及C语言编译程序或Linux虚拟环境。⒍实验总体要求培养计算机专业的学生的系统程序设计能力,是操作系统课程的一个非常重要的环节。经过操作系统上机实验,能够培养学生程序设计的方法和技巧,提高学生编制清晰、合理、可读性好的系统程序的能力,加深对操作系统课程的理解。使学生更好地掌握操作系统的基本概念、基本原理、及基本功能,具有分析实际操作系统、设计、构造和开发现代操作系统的基本能力。实验要求做到:详细描述实验设计思想、程序结构及各模块设计思路;详细描述程序所用数据结构及算法;明确给出测试用例和实验结果;为增加程序可读性,在程序中进行适当注释说明;认真进行实验总结,包括:设计中遇到的问题、解决方法与收获等;实验报告撰写要求结构清晰、描述准确逻辑性强;实验过程中,同学之间能够进行讨论互相提高,但绝对禁止抄袭。⒎本实验的重点、难点及教学方法建议重点:理解进程调度中PCB的设计,以实现对进程的调度。难点:进程调度程序的设计,设备管理程序的设计。教学方法建议:力争在本指导书的帮助下,独立设计程序以加深理解。

实验一分析操作系统所面临的操作需求(一)实验目的使学生理解操作系统所面临的操作需求,掌握操作系统中的进程管理、存储管理、设备管理和文件管理等功能。(二)实验内容1.

分析操作系统所面临的操作需求;2.

熟悉实验环境;3.

资料搜集与整理,进行实验的前期准备。熟悉编程环境

本课程中的实验题目既能够在windows下用控制台应用程序实现,也能够在linux下用全屏幕程序实现。这里我们首先介绍在windows下用vc++6.0设计控制台应用程序的步骤,然后介绍在linux下用C语言编写全屏幕程序的步骤。windows的控制台应用程序

图1-1图1-2图1-3步骤1:开机,单击“开始”按钮,选择“程序

->Microsoft

Visual

Studio

6.0->Microsoft

Visual

C++6.0”进入Microsoft

Visual

步骤2:在Microsoft

Visual

C++6.0中,单击“File”菜单,选择“New”菜单命令,见图1-2。

步骤3:在“Files”选项卡中选择“C++

Source

File”,见图1-32.

linux的vi应用编程登录Linux是一个多用户多任务操作系统,多个用户能够拥有自己独立的用户账号登录提示:RedHatLinuxrelease6.0(Hedwing)Kernel2.2.5-15onani686Login:此时输入用户户名(账号)并键入回车,则系统显示“passward”。在输入密码和回车。登录后:[root@hawk/root]##表示是按root方式登录,$表示是普通用户。Linux大小写敏感,用“-”加参数zlinux:~#ls–FHowTo/HowToMin/linux@nag/sag/获取帮助:Linux带有联机手册,能够用man命令来阅读Zlinux:~$manls虚拟终端Linux可有多个用户登录到同一个计算机,但一般微机只有一个终端难以体现。能够使用多个虚拟终端,用Alt+F1、Alt+F2等来切换。退出系统在停止使用系统时,要退出系统。具体方法:exit或logout,或Ctrl+D关机如果没有用户在使用系统,能够关机。可是不能直接关闭电源,而要按正常顺序关机。一般用户是不能关机的,只有root用户能够关机。方法:能够使用halt或shutdown命令,也能够同时键入Ctrl+Alt+Del。Windows虚拟机环境:登录到系统点击桌面“VMware”图标——>VmwareWorkstation窗口——>Commands——>Startthisvirtualmachine进入fedora后,用户名:root口令:123456使用编辑器vi编辑文件进入linux的文本模式之后,在命令行键入vifilename.c然后回车。下面作一些简单的解释:首先vi命令是打开vi编辑器。后面的filename.c是用户即将编辑的c文件名字,注意扩展名字是.c;当然,vi编辑器功能很强,能够用它来编辑其它格式的文件,比如汇编文件,其扩展名字是.s;也能够直接用vi打开一个新的未命名的文件,当保存的时候再给它命名,只是这样做不很方便。最基本的命令I:当进入刚打开的文件时,不能写入信息,这时按一下键盘上的I键(insert),插入的意思,就能够进入编辑模式了。如下图所示:a与i是相同的用法当文件编辑完后,需要保存退出,这时需要经过以下几个步骤:1)按一下键盘上的Esc键;2)键入冒号(:),紧跟在冒号后面是wq(意思是保存并退出)。如果不想保存退出,则在第二步键入冒号之后,键入!q(不带w,机尾部保存)。如下图所示:退出vi编辑器的编辑模式之后,要对刚才编写的程序进行编译。编译的命令是:gccfilename.c[-ooutputfilename],其中gcc是c的编译器。参数:filename.c是刚才编辑的c文件(当然也能够是以前编写好的c文件);后面中括号里面的参数是可选的,它是一个输出文件。如果不选,默认的输出文件是a.out,选了之后输出文件就是outputfilename.out.最后一步是运行程序,方法如下:./outputfilename.out

实验二进程管理(一)实验目的掌握临界区的概念及临界区的设计原则;掌握信号量的概念、PV操作的含义以及应用PV操作实现进程的同步与互斥;分析进程争用资源的现象,学习解决进程互斥的方法;掌握进程的状态及状态转换;掌握常见的进程调度算法。(二)实验内容1.分析进程的同步与互斥现象,编程实现经典的进程同步问题——生产者消费者问题的模拟;2.

编写允许进程并行执行的进程调度程序,在常见的进程(作业)调度算法:先来先服务算法、短作业优先算法、最高响应比优先算法、高优先权优先算法等调度算法中至少选择三种调度算法进行模拟,并输出平均周转时间和平均带权周转时间。本实验涉及内容较多,能够在两个题目里选择一个完成。编程实现经典的进程同步问题——生产者消费者问题的模拟模拟实现用同步机构避免发生进程执行时可能出现的与时间有关的错误。进程是程序在一个数据集合上运行的过程,进程是并发执行的,也即系统中的多个进程轮流地占用处理器运行。我们把若干个进程都能进行访问和修改的那些变量称为公共变量。由于进程是并发地执行的,因此,如果对进程访问公共变量不加限制,那么就会产生“与时间有关”的错误,即进程执行后所得到的结果与访问公共变量的时间有关。为了防止这类错误,系统必须要用同步机构来控制进程对公共变量的访问。一般说,同步机构是由若干条原语——同步原语——所组成。本实验要求模拟PV操作同步机构的实现,模拟进程的并发执行,了解进程并发执行时同步机构的作用。此次用到的数据结构知识如下:typedefstructPcb{ charname[10];//进程名 charstate[10];//运行状态 charreason[10];//若阻塞,其原因 intbreakp;//断点保护 structPcb*next;//阻塞时的顺序}Pcb,*link;进程名状态等待原因断点后继进程进程控制块结构定义两个进程:linkp1;//生产者进程,linkc1;//消费者进程。pc程序计数器和linkready;就绪队列,linkb_s1;s1阻塞队列,linkb_s2;s2阻塞队列。实验指导:h头文件#include<string.h>#include<ctype.h>#include<malloc.h>/*malloc()等*/#include<limits.h>/*INT_MAX等*/#include<stdio.h>/*EOF(=^Z或F6),NULL*/#include<stdlib.h>/*atoi()*/#include<io.h>/*eof()*/#include<math.h>/*floor(),ceil(),abs()*/#include<process.h>/*exit()*/#include<iostream>usingnamespacestd;#include<time.h>#defineBUF10//缓存的大小#defineMAX20//最大能够输入的字符h头文件//数据结构的定义和全局变量typedefstructPcb{ charname[10];//进程名 charstate[10];//运行状态 charreason[10];//若阻塞,其原因 intbreakp;//断点保护 structPcb*next;//阻塞时的顺序}Pcb,*link;ints1,s2;//信号量linkp1;//生产者进程linkc1;//消费者进程charstr[MAX];//输入的字符串charbuffer[BUF];//缓冲池intlen;//输入长度intsp=0;//string的指针intin=0;//生产者指针intout=0;//消费者指针chartemp;//供打印的临时产品charrec_p[MAX];//生产记录intrp1=0;//生产记录指针charrec_c[MAX];//消费记录intrp2=0;//消费记录指针linkready;//就绪队列linkb_s1;//s1阻塞队列linkb_s2;//s2阻塞队列intpc;//程序计数器intcount;//字符计数器intcon_cnt;//消费计数器h头文件voidinit();//初始化voidp(ints);//P操作voidv(ints);//V操作voidblock(ints);//阻塞函数voidwakeup(ints);//唤醒函数voidcontrol();//处理机调度voidprocessor();//处理机执行voidprint();//打印函数voidinit(){//初始化 s1=BUF; s2=0; p1=(link)malloc(sizeof(Pcb));//建立新的结点,并初始化为生产者 strcpy(p1->name,"Producer"); strcpy(p1->state,"Ready"); strcpy(p1->reason,"Null"); p1->breakp=0; p1->next=NULL; c1=(link)malloc(sizeof(Pcb));//建立新的结点,并初始化为消费者 strcpy(c1->name,"Consumer"); strcpy(c1->state,"Ready"); strcpy(c1->reason,"Null"); c1->breakp=0; c1->next=NULL; ready=p1; ready->next=c1;//初始化为生产进程在前,消费进程在后 c1->next=NULL; b_s1=NULL; b_s2=NULL;//阻塞进程为NULL pc=0; con_cnt=0;//消费计数器}voidp(ints){ if(s==1){//p(s1) s1--; if(s1<0) block(1);//阻塞当前生产进程 else{ printf("\t*s1信号申请成功!\n"); ready->breakp=pc;//保存断点 } } else{//p(s2) s2--; if(s2<0) block(2);//阻塞当前消费进程 else{ printf("\t*s2信号申请成功!\n"); ready->breakp=pc;//保存断点 } }}voidv(ints){ if(s==1){//v(s1) s1++; if(s1<=0) wakeup(1);//唤醒生产进程 ready->breakp=pc;//保存断点 } else{//v(s2) s2++; if(s2<=0) wakeup(2);//唤醒消费进程 ready->breakp=pc;//保存断点 }}voidblock(ints){//阻塞函数的定义 linkp; intnum1=0; intnum2=0; if(s==1){//生产进程 strcpy(p1->state,"Block");//改变状态 strcpy(p1->reason,"S1");//说明原因 p=b_s1; while(p){ num1++; p=p->next;//p的值为NULL,表示队尾 } if(!b_s1) b_s1=p1; else p=p1; p1->next=NULL; printf("\t*p1生产进程阻塞了!\n"); ready->breakp=pc;//保存断点 ready=ready->next;//在就绪队列中去掉,指向下一个 num1++; } else{//消费进程 strcpy(c1->state,"Block"); strcpy(c1->reason,"S2"); p=b_s2; while(p){ num2++; p=p->next;//p的值为NULL,表示队尾 } if(!b_s2) b_s2=c1; else p=c1; ready->breakp=pc;//保存断点 ready=ready->next;//在就绪队列中去掉,指向下一个 c1->next=NULL; printf("\t*c1消费进程阻塞了!\n"); num2++; } printf("\t*阻塞的生产进程个数为:%d\n",num1); printf("\t*阻塞的消费进程个数为:%d\n",num2);}voidwakeup(ints){//唤醒函数的定义 linkp; linkq=ready; if(s==1){//唤醒b_s1队首进程,生产进程队列 p=b_s1; b_s1=b_s1->next;//阻塞指针指向下一个阻塞进程 strcpy(p->state,"Ready"); strcpy(p->reason,"Null"); while(q)//插入就绪队列 q=q->next; q=p; p->next=NULL; printf("\t*p1生产进程唤醒了!\n"); } else{//唤醒b_s2队首进程,消费进程队列 p=b_s2; b_s2=b_s2->next;//阻塞指针指向下一个阻塞进程 strcpy(p->state,"Ready"); strcpy(p->reason,"Null"); while(q->next)//插入就绪队列 q=q->next; q->next=p; p->next=NULL; printf("\t*c1消费进程唤醒了!\n"); }}voidcontrol()//处理器调度程序{ intrd; intnum=0; linkp=ready;if(ready==NULL)//若无就绪进程,结束 return; while(p)//统计就绪进程个数 { num++; p=p->next;//最终p变为NULL } printf("\t*就绪进程个数为:%d\n",num); time_tt; srand((unsigned)time(&t)); rd=rand()%num;//随机函数产生随机数 if(rd==1){ p=ready; ready=ready->next; ready->next=p; p->next=NULL; strcpy(ready->state,"Run"); strcpy(ready->next->state,"Ready"); } else strcpy(ready->state,"Run"); pc=ready->breakp;}voidprocessor(){//模拟处理器指令执行 if(strcmp(ready->name,"Producer")==0)//当前进程为生产者 switch(pc) {case0://produce printf("\t*生产者生产了字符%c\n",str[sp]); rec_p[rp1]=str[sp];//添加到生产记录 sp=(sp+1)%len; pc++; ready->breakp=pc;//保存断点 break; case1://p(s1) pc++; p(1); break; case2://put buffer[in]=rec_p[rp1];//放到缓冲区 printf("\t*%c字符成功入驻空缓存!\n",buffer[in]); rp1++; in=(in+1)%BUF; pc++; ready->breakp=pc;//保存断点 break; case3://v(s2) pc++; printf("\t*释放一个s2信号\n"); v(2); break; case4://goto01 printf("\t*生产进程goto0操作\n"); pc=0; count--;//剩余字符个数减1 printf("\t*剩余字符count=%d个\n",count); ready->breakp=pc;//保存断点 if(count<=0){//生产结束 printf("\t*生产者结束生产!\n"); strcpy(p1->state,"Stop"); strcpy(p1->reason,"Null"); ready->breakp=-1; ready=ready->next;//在就绪队列中去掉 } } else//当前进程为消费者 switch(pc) { case0://p(s2) pc++; p(2); break; case1://get printf("\t*消费者取字符!\n"); temp=buffer[out]; out=(out+1)%BUF; pc++; ready->breakp=pc;//保存断点 break; case2://v(s1) pc++; printf("\t*释放一个s1\n"); v(1); break; case3://consume printf("\t*消费了字符%c\n",temp); rec_c[rp2]=temp;//添加到消费记录 rp2++; con_cnt++; if(con_cnt>=len){ strcpy(c1->state,"Stop");//完成态 c1->breakp=-1; return; } pc++; ready->breakp=pc;//保存断点 break; case4://goto0 printf("\t*消费进程goto0操作\n"); pc=0; ready->breakp=pc;//保存断点 }}voidprint(){ inti,j; printf("生产者消费者模拟\n"); printf("*模拟过程的字符串为:\t"); printf("%s\n",&str); printf("*已生产:"); for(j=0;j<=rp1;j++) printf("%c",rec_p[j]); printf("\n*空缓存:"); for(j=rp2;j<=rp1;j++) printf("%c",buffer[j]); printf("\n*已消费:"); for(j=0;j<=rp2;j++) printf("%c",rec_c[j]); printf("\n进程控制块的信息\n"); printf("进程名\t\t状态\t等待原因\t断点\n"); printf("%s\t%s\t%s\t\t%d\n\n",p1->name,p1->state,p1->reason,p1->breakp); printf("%s\t%s\t%s\t\t%d\n",c1->name,c1->state,c1->reason,c1->breakp); printf("\n"); printf("1.继续0.退出\n"); scanf("%d",&i); if(i==0){ exit(0); }}主程序#include"a.h"#include"b.h"#include"c.h"voidmain(){ printf("*生产者消费者模拟\n"); printf("\n"); printf("*请输入字符串:\n"); scanf("%s",str);//string数组存放将要产生的字符 len=strlen(str); count=len;//输入字符的个数 init();//初始化 while(con_cnt<len)//消费完所有的字符为结束 { system("cls");//清屏操作 printf("模拟指令流程\n"); control();//处理器调度程序 processor();//模拟处理器指令执行 print();//输出显示各个信息 } printf("\n程序结束!\n");}

进程调度算法模拟进程管理是操作系统中的重要功能,用来创立进程、撤消进程、实现进程状态转换,它提供了在可运行的进程之间复用CPU的方法。在进程管理中,进程调度是核心,因为在采用多道程序设计的系统中,往往有若干个进程同时处于就绪状态,当就绪进程个数大于处理器数目时,就必须依照某种策略决定哪些进程优先占用处理器。本实验模拟在单处理器情况下的进程调度,目的是加深对进程调度工作的理解,掌握不同调度算法的优缺点。设计一个按先来先服务、时间片轮转法、优先数调度算法实现处理器调度的程序。实验指导:#include<stdio.h>#include<stdlib.h>#include<string.h>#include<conio.h>typedefstructnode{ charname[10];/*进程标识符*/ intprio;/*进程优先数*/ intround;/*进程时间轮转时间片*/ intcputime;/*进程占用CPU时间*/ intneedtime;/*进程到完成还要的时间*/ intarrivetime;/*进程到达时间*/ intstarttime;/*进程开始时间*/ intfinishtime;/*进程完成时间*/ intservicetime;/*进程服务时间*/floatturnaroundtime;/*进程周转时间*/floatweightedturnaroundtime;/*进程带权周转时间*/ intcount;/*计数器*/ charstate;/*进程的状态*/ structnode*next;/*链指针*/}PCB; PCB*finish,*ready,*tail,*run;/*队列指针*/ intN;/*进程数*//*将就绪队列中的第一个进程投入运行*/voidfirstin(){ run=ready;/*就绪队列头指针赋值给运行头指针*/ run->state='R';/*进程状态变为运行态*/ ready=ready->next;/*就绪对列头指针后移到下一进程*/}/*****标题输出函数*****/voidprt1(chara){ switch(a) { case1:/*优先数法*/ printf("名字进程占用CPU时间进程到完成还要的时间优先级数状态\n");break; case2:/*时间片算法*/ printf("名字进程占用CPU时间进程到完成还要的时间计数器时间片状态\n");break; case3:/*先来先服务算法*/ printf("名字到达时间开始时间服务时间完成时间周转时间带权周转时间状态\n");break; default:break; }}/*****进程PCB输出*****/voidprt2(chara,PCB*q){ switch(a) { case1:/*优先数法的输出*/ printf("%-10s\t%-10d\t%-10d\t%-10d\t%c\n",q->name, q->cputime,q->needtime,q->prio,q->state);break; case2:/*轮转法的输出*/ printf("%-10s%-20d%-15d%-10d%-10d%-c\n",q->name, q->cputime,q->needtime,q->count,q->round,q->state);break; case3:/*先来先服务算法输出*/ printf("%s%10d%10d%10d%10d%10.1f%10.2f\t\t%c\n",q->name,q->arrivetime,q->starttime,q->servicetime,q->finishtime, q->turnaroundtime,q->weightedturnaroundtime,q->state);break; default:break; }}/*****输出函数*****/voidprt(charalgo){ PCB*p; prt1(algo);/*输出标题*/ if(run!=NULL)/*如果运行指针不空*/ prt2(algo,run);/*输出当前正在运行的PCB*/ p=ready;/*输出就绪队列PCB*/ while(p!=NULL){ prt2(algo,p); p=p->next;} p=finish;/*输出完成队列的PCB*/ while(p!=NULL){ prt2(algo,p); p=p->next;} getch();/*压任意键继续*/}/*****优先数的插入算法*****/voidinsert1(PCB*q){ PCB*p1,*s,*r; intb; s=q;/*待插入的PCB指针*/ p1=ready;/*就绪队列头指针*/ r=p1;/*r做p1的前驱指针*/ b=1;while((p1!=NULL)&&b)/*根据优先数确定插入位置*/if(p1->prio>=s->prio){ r=p1; p1=p1->next;}else b=0; if(r!=p1)/*如果条件成立说明插入在r与p1之间*/{ r->next=s; s->next=p1;} else{ s->next=p1;/*否则插入在就绪队列的头*/ ready=s;}}/*****轮转法插入函数*****/voidinsert2(PCB*p2){tail->next=p2;/*将新的PCB插入在当前就绪队列的尾*/tail=p2;p2->next=NULL;}/*****先来先服务插入函数*****/voidinsert3(PCB*q){ PCB*p1,*s,*r; intb; s=q;/*指针s指向新要插入的进程*/ p1=ready;/*指针p1指向原来的进程的对首*/ r=p1;/*使用指针r指向p1前面的进程*/ b=1; while((p1!=NULL)&&b) if(p1->arrivetime<s->arrivetime) { r=p1; p1=p1->next; } else b=0; if(r!=p1) { r->next=s; s->next=p1; } else { s->next=p1; ready=s; }}/*****优先数创立初始PCB信息*****/voidcreate1(charalg){ PCB*p; inti,time; charna[10]; ready=NULL;/*就绪队列头指针*/ finish=NULL;/*完成队列头指针*/ run=NULL;/*运行队列头指针*/ printf("请输入进程的名字和运行所需要的时间\n");/*输入进程标识和所需时间创立PCB*/ for(i=1;i<=N;i++){ p=(PCB*)malloc(sizeof(PCB)); scanf("%s",na); scanf("%d",&time); strcpy(p->name,na); p->cputime=0; p->needtime=time; p->state='W'; p->prio=50-time; if(ready!=NULL)/*就绪队列不空则调用插入函数插入*/ insert1(p); else{ p->next=ready;/*创立就绪队列的第一个PCB*/ ready=p;}} voidclrscr(void); printf("优先级调度算法模拟输出结果:\n"); printf("*******************************************************************\n"); prt(alg);/*输出进程PCB信息*/ run=ready;/*将就绪队列的第一个进程投入运行*/ ready=ready->next; run->state='R';}/*****轮转法创立进程PCB*****/voidcreate2(charalg){ PCB*p; inti,time; charna[10]; ready=NULL; finish=NULL; run=NULL; printf("请输入进程的名字和运行所需要的时间\n"); for(i=1;i<=N;i++){ p=(PCB*)malloc(sizeof(PCB)); scanf("%s",na); scanf("%d",&time); strcpy(p->name,na); p->cputime=0; p->needtime=time; p->count=0;/*计数器*/ p->state='W'; p->round=2;/*时间片*/ if(ready!=NULL) insert2(p); else{ p->next=ready; ready=p; tail=p;}} voidclrscr(void); printf("时间片轮转法模拟输出结果:\n"); printf("********************************************************************\n"); prt(alg);/*输出进程PCB信息*/ run=ready;/*将就绪队列的第一个进程投入运行*/ ready=ready->next; run->state='R';}/*****先来先服务算法创立PCB*****/voidcreate3(charalg){ PCB*p; inti;ready=NULL; run=NULL; finish=NULL; printf("请输入进程的名字、到达时间和运行所需要的时间\n"); for(i=0;i<N;i++) {p=(PCB*)malloc(sizeof(PCB)); scanf("%s",p->name); scanf("%d",&p->arrivetime); scanf("%d",&p->servicetime);p->starttime=0; p->finishtime=0; p->turnaroundtime=0; p->weightedturnaroundtime=0; p->state='W'; if(ready!=NULL) insert3(p); else { p->next=ready; ready=p; } } voidclrscr(void); printf("先来先服务算法模拟输出结果:\n"); printf("***************************************************************************\n"); prt(alg); run=ready;/*将就绪队列的第一个进程投入运行*/ ready=ready->next; run->state='R';}/*****优先数调度算法*****/voidpriority(charalg){while(run!=NULL)/*当运行队列不空时,有进程正在运行*/{run->cputime=run->cputime+1;run->needtime=run->needtime-1;run->prio=run->prio-3;/*每运行一次优先数降低3个单位*/if(run->needtime==0)/*如所需时间为0将其插入完成队列*/{run->next=finish;finish=run;run->state='F';/*置状态为完成态*/run=NULL;/*运行队列头指针为空*/if(ready!=NULL)/*如果就绪队列不空*/firstin();/*将就绪对列的第一个进程投入运行*/}else/*没有运行完同时优先数不是最大,则将其变为就绪态插入到就绪队列*/if((ready!=NULL)&&(run->prio<ready->prio)){run->state='W';insert1(run);firstin();/*将就绪队列的第一个进程投入运行*/}prt(alg);/*输出进程PCB信息*/}}/*****时间片轮转法*****/voidroundrun(charalg){while(run!=NULL){run->cputime=run->cputime+1;run->needtime=run->needtime-1;run->count=run->count+1;if(run->needtime==0)/*运行完将其变为完成态,插入完成队列*/{run->next=finish;finish=run;run->state='F';run=NULL;if(ready!=NULL)firstin();/*就绪对列不空,将第一个进程投入运行*/}elseif(run->count==run->round)/*如果时间片到*/{run->count=0;/*计数器置0*/if(ready!=NULL)/*如就绪队列不空*/{run->state='W';/*将进程插入到就绪队列中等待轮转*/insert2(run);firstin();/*将就绪对列的第一个进程投入运行*/}} prt(alg);/*输出进程信息*/}}/*****先来先服务调度算法*****/voidFIFO(charalg){inttime; while(run!=NULL) { time=run->arrivetime>time?run->arrivetime:time;run->starttime=time; time=time+run->servicetime; run->finishtime=time; run->turnaroundtime=run->finishtime-run->arrivetime; run->weightedturnaroundtime=run->turnaroundtime/run->servicetime; run->next=finish; finish=run; run->state='F'; run=NULL; if(ready!=NULL){ run=ready; run->state='R'; ready=ready->next;} prt(alg); }} /*****主函数*****/intmain(){charalgo;/*算法标记*/voidclrscr(void);charmainmenu;do{ system("cls");/*清屏*/ printf("\n温馨提示:为保证您的操作得到预期效果,请规范输入您的信息^_^\n"); printf("\n\n"); printf("\t\t+━━━━━━━━━━━━━━━━━━━━━━━━+\n");printf("\t\t||欢迎进入进程调度算法模拟演示系统||\n");printf("\t\t|┗━━━━━━━━━━━━━━━━┛|\n");printf("\t\t||\n");printf("\t\t|●[1]优先级算法演示|\n");printf("\t\t||\n");printf("\t\t|●[2]时间片轮转算法演示|\n");printf("\t\t||\n");printf("\t\t|●[3]先来先服务算法演示|\n");printf("\t\t||\n"); printf("\t\t|●[4]退出系统|\n"); printf("\t\t||\n"); printf("\t\t+━━━━━━━━━━━━━━━━━━━━━━━━+\n");printf("请输入您的选择:\n");scanf("%d",&algo);/*输入字符确定算法*/ switch(algo) { case1: printf("您选择的是优先级算法模拟进程调度\n\n"); printf("请输入进程数目\n"); scanf("%d",&N);/*输入进程数*/ create1(algo);/*优先数法*/ priority(algo); break; case2: printf("您选择的是时间片轮转算法模拟进程调度\n\n"); printf("请输入进程数目\n"); scanf("%d",&N);/*输入进程数*/ create2(algo);/*轮转法*/ roundrun(algo); break; case3: printf("您选择的是先来先服务算法模拟进程调度\n\n"); printf("请输入进程数目\n"); scanf("%d",&N);/*输入进程数*/ create3(algo); FIFO(algo); break; case4: printf("欢迎您再次使用进程调度算法模拟系统!\n"); exit(4); break; default: printf("输入有误\n"); break; }printf("\n是否继续操作(y/n)?");fflush(stdin);mainmenu=getchar(); }while(mainmenu=='y'||mainmenu=='Y');return0;}

实验三存储管理(一)实验目的掌握物理内存和虚拟内存的基本概念;掌握重定位的基本概念及其要点,理解逻辑地址与绝对地址;掌握各种存储管理的实现方法,包括基本原理、地址变换和缺页中断、主存空间的分配及分配算法;掌握常见淘汰算法。(二)实验内容编写一个模拟的动态页式存储管理程序,实现对动态页式存储的淘汰算法的模拟(在先进先出淘汰算法、最近最少使用淘汰算法、最不经常使用淘汰算法三种算法中至少选择两种进行模拟)并计算各个算法的缺页率;而且页面淘汰算法在淘汰一页时,只将该页在页表中抹去,而不再判断它是否被改写过,也不将它写回到辅存。实验指导:#include<iostream.h>#definen12#definem3intpage[n];//保存需要访问的页面inti,j,q,mem[m]={0},List[m][n],sum;charflag,f[n];voidInit();voidFIFO();voidLRU();voidmain(){ cout<<"*********************实验***********************"<<endl; cout<<"┏━━━━━━━━━━━━━━━━━━━━━━━┓"<<endl; cout<<"┃页面调度算法的模拟实现┃"<<endl; cout<<"┠───────────────────────┨"<<endl; cout<<"┃先进先出算法FIFO┃"<<endl; cout<<"┃最近最少使用算法LRU┃"<<endl; cout<<"┗━━━━━━━━━━━━━━━━━━━━━━━┛"<<endl; cout<<"请输入页面访问序列:\n"<<""; for(i=0;i<n;i++) cin>>page[i];cout<<endl; FIFO(); Init(); LRU();}voidInit()//初始化函数{ sum=0;//初始化计算缺页次数的变量 for(inti=0;i<m;i++) mem[i]=0; for(i=0;i<m;i++) for(j=0;j<n;j++) List[i][j]=0;}voidFIFO(){ for(i=0;i<n;i++)//查页表,看是否缺页 { q=0; while((page[i]!=mem[q])&&(q!=m)) q++; if(q==m) flag='*';//缺页,则置标志flag为'*' else flag=''; if(flag=='*') { for(j=m-1;j>0;j--)//淘汰最先调入的页面调入当前访问的 mem[j]=mem[j-1]; mem[0]=page[i]; } for(j=0;j<m;j++) List[j][i]=mem[j]; f[i]=flag; } cout<<"0代表为空,*代表有缺页:\n"; cout<<endl; cout<<"FIFO算法结果"<<endl; for(i=0;i<m;i++) { for(j=0;j<n;j++) cout<<List[i][j]<<""; cout<<endl; } for(i=0;i<n;i++) { if(f[i]=='*') sum++; cout<<f[i]<<""; } cout<<"\n"<<endl; cout<<"缺页次数是:"<<sum<<"缺页率是:"<<(double)sum/12<<endl;}voidLRU(){ for(i=0;i<n;i++)//查页表,看是否缺页 { q=0; while((page[i]!=mem[q])&&(q!=m)) q++; if(q==m) flag='*';//缺页,则置标志flag为'*' else flag=''; for(j=q;j>0;j--) mem[j]=mem[j-1]; mem[0]=page[i]; for(j=0;j<m;j++) List[j][i]=mem[j]; f[i]=flag; } cout<<endl; cout<<"LRU算法结果"<<endl; for(i=0;i<m;i++) { for(j=0;j<n;j++) cout<<List[i][j]<<""; cout<<endl; } for(i=0;i<n;i++) { if(f[i]=='*') sum++; cout<<f[i]<<""; } cout<<endl; cout<<""<<endl; cout<<"缺页次数是:"<<sum<<"缺页率是:"<<(double)sum/12<<endl;}

实验四设备管理(一)实验目的掌握独占设备的使用方式,以及设备的分配和回收;掌握用死锁避免方法来处理申请独占设备可能造成的死锁。(二)实验内容用死锁避免方法来处理申请独占设备可能造成的死锁,程序实现对银行家算法的模拟。设计五个进程{P0,P1,P2,P3,P4}共享三类资源{A,B,C}的系统,{A,B,C}的资源数量分别为10,5,7。进程可动态地申请资源和释放资源,系统按各进程的申请动态地分配资源。要求程序具有显示和打印各进程的某一时刻的资源分配表和安全序列;显示和打印各进程依次要求申请的资源号以及为某进程分配资源后的有关资源数据的情况。实验指导:#include<iostream.h>#include<string.h>#include<stdio.h>#include<iomanip>#definen10#definetrue1#definefalse0intN;//资源总类intM; //总进程数intAvailable[50];intMax[50][50];intAllocation[50][50]={0};intNeed[50][50]={0};intWork[50]={0}; intTemp[50]={0};//存放安全序列号charName[50]={0};intSum[50]={0};intRequest[50]={0};voidPrint(){ intk=0; cout<<" ***********资源分配表***********"<<endl; cout<<"Process"<<"Max"<<"Allocation"<<"Need"<<"Available"<<endl; cout<<" ABC"<<"ABC"<<"ABC"<<"ABC"<<endl; for(inti=0;i<M;i++) { cout<<"P"<<i<<""; for(intj=0;j<N;j++) cout<<""<<Max[i][j]; cout<<""; for(j=0;j<N;j++) cout<<""<<Allocation[i][j]; cout<<""; for(j=0;j<N;j++) cout<<""<<Need[i][j]; cout<<""; for(j=0;j<N;j++) { if(k!=3) { cout<<""<<Available[j]; k++; } } cout<<endl; }}voidCreate(){ inti,j; cout<<"请输入您要创立进程的数量:"<<endl; cin>>M; cout<<"请输入各类资源的总数:("<<N<<"个)"<<endl; for(i=0;i<N;i++) cin>>Sum[i];k1: cout<<endl; cout<<"请输入各类进程所需要资源最大数目:("<<N*M<<"个)"<<endl; for(i=0;i<M;i++) for(j=0;j<N;j++) { cin>>Max[i][j]; if(Max[i][j]>Sum[j]) { cout<<"占有资源超过了声明的该资源总数,请重新输入!"<<endl; gotok1; } } k2: cout<<endl; cout<<"请输入各类进程已分配的各类资源的数目:("<<N*M<<"个)"<<endl; for(i=0;i<M;i++) for(j=0;j<N;j++) { cin>>Allocation[i][j]; if(Allocation[i][j]>Max[i][j]) { cout<<"占有资源超过了声明的该资源总数,请重新输入!"<<endl; gotok2; } } intp; for(i=0;i<N;i++) { p=Sum[i]; for(j=0;j<M;j++) p=p-Allocation[j][i]; Available[i]=p; } for(i=0;i<M;i++) for(j=0;j<N;j++) Need[i][j]=Max[i][j]-Allocation[i][j];}voidrestore(inti){ intj; for(j=0;j<N;j++) { Available[j]+=Request[j]; Allocation[i][j]-=Request[j]; Need[i][j]+=Request[j]; }}intchangedata(inti){ intj; for(j=0;j<N;j++) { Available[j]+=Request[j]; Allocation[i][j]-=Request[j]; Need[i][j]+=Request[j]; } return1;}intSafe()//处理传过来的第几个进程{ inti=0; intk=0; intm; intapply,Finish[50]={0}; intj,flag=0; for(i=0;i<N;i++) Work[i]=Available[i]; for(i=0;i<M;i++) { apply=0; for(j=0;j<N;j++) { if(Finish[i]==false&&Need[i][j]<=Work[j]) { apply++; if(apply==N) { for(m=0;m<N;m++) Work[m]=Work[m]+Allocation[i][m]; Finish[i]=true; Temp[k++]=i; i=-1; flag; } } }} for(i=0;i<M;i++) { if(Finish[i]==false) { cout<<"系统不安全!!!本次资源申请不成功!!!"<<endl; return-1; } } cout<<"经安全性检查,系统安全,本次分配成功!!"<<endl; cout<<"安全序列号"; for(i=0;i<M-1;i++) cout<<"P"<<Temp[i]<<","; cout<<"P"<<Temp[i]<<">"<<endl; cout<<endl; return0;}voiddijkstra(){ charch; inti=0,j=0; ch='y'; cout<<"请输入你要请求的资源进程号(0-"<<M-1<<"):"<<endl; cin>>i; cout<<"请输入进程"<<i<<"请求Request变量"<<endl; for(i=0;i<N;i++) { cout<<Name[j]<<":"; cin>>Request[i]; } for(i=0;i<N;i++) { if(Request[i]>Need[j][i]) { cout<<"进程"<<i<<"申请的资源大于她需要的资源"; cout<<"分配不合理,不予分配!"<<endl; ch='n'; break; } else if(Request[j]>Available[j]) { cout<<"进程"<<i<<"申请的资源大于系统可利用的资源"; cout<<"分配出错,不予分配!"<<endl; ch='n'; break; } if(ch='y') changedata(i); Print(); Safe(); if(Safe()==1) restore(i); } }intmain(){ intc; Create(); Print(); Safe(); while(c) { cout<<" 银行家算法"<<endl; cout<<"1分配资源"<<endl; cout<<"2离开"<<endl; cout<<"请选择功能号:"<<endl; cin>>c; switch(c) { case1:dijkstra();break; case0:c=0;break; default:cout<<"请正确选择功能号(0--1)"<<endl;break; } } return1;}

实验五文件管理(一)实验目的掌握文件的存取方法;掌握文件的逻辑结构和物理结构;掌握存储空间的分配和回收;掌握磁盘管理与调度。(二)实验内容用程序模拟磁盘的调度过程,并计算各磁盘调度算法包括先来先服务算法、最短寻道时间优先算法、扫描算法和循环扫描算法的平均寻道长度。本实验是模拟操作系统的磁盘寻道方式,运用磁盘访问顺序的不同来设计磁盘的调度算法。实现的磁盘调度算法有FCFS,SSTF,SCAN,CSCAN和NStepSCAN算法。设定开始磁道号寻道范围,依据起始扫描磁道号和最大磁道号数,随机产生要进行寻道的磁道号序列。选择磁盘调度算法,显示该算法的磁道访问顺序,计算出移动的磁道总数和平均寻道总数。按算法的寻道效率进行排序,并对各算法的性能进行分析比较。实验指导:#include<stdio.h>#include<math.h>voidFCFS(intb[],intn,intinit){ inti,s,sum; inta[20]; for(i=0;i<n;i++) a[i]=b[i]; s=init; sum=0; for(i=0;i<n;i++){ printf("第%d次访问的磁道:%d\n",i+1,a[i]); sum+=abs(s-a[i]); s=a[i]; } printf("平均寻道长度:%f\n",sum*1.0/n);}voidSSTF(intb[],intn,intk){ inti,j,s,sum=0,p; inta[20]; for(i=0;i<n;i++) a[i]=b[i]; for(i=n-1;i>=0;i--){ s=a[0]; p=0; for(j=0;j<=i;j++) if(abs(a[j]-k)<abs(s-k)){ s=a[j]; p=j; } a[p]=a[i]; printf("第%d次访问的磁道:%d\n",n-i,s); sum+=abs(s-k); k=s; } printf("平均寻道长度:%f\n",sum*1.0/n);}voidSCAN1(intb[],intn,intk){ inti,j,s,sum=0,p,biaoji; inta[20]; for(i=0;i<n;i++) a[i]=b[i]; for(i=n-1;i>=0;i--){ biaoji=0; for(j=0;j<=i;j++) if(a[j]-k<0){ biaoji=1; p=j; break; } if(biaoji==1){ s=a[p]; for(j=0;j<=i;j++) if(a[j]<k&&k-a[j]<k-s) { s=a[j]; p=j; } a[p]=a[i]; printf("第%d次访问的磁道:%d\n",n-i,s); sum+=k-s; k=s; } else{ s=a[0]; for(j=0;j<=i;j++) if(a[j]-k<=s-k) { s=a[j]; p=j; } a[p]=a[i]; printf("第%d次访问的磁道:%d\n",n-i,s); sum+=abs(k-s); k=s; } } printf("平均寻道长度:%f\n",sum*1.0/n);}voidSCAN2(intb[],intn,intk){ inti,j,s,sum=0,p,biaoji; inta[20]; for(i

温馨提示

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

评论

0/150

提交评论