当前位置:文档之家› 操作系统课程设计

操作系统课程设计

课程设计说明书(操作系统)题目:进程调度院系:计算机科学与工程学院专业班级:信息安全13—2学号: 20133029xx学生姓名: xx指导教师:xx2015年12月 15日ﻬ安徽理工大学课程设计(论文)任务书计算机科学与工程学院安徽理工大学课程设计(论文)成绩评定表摘要现代计算机系统中,进程就是资源分配与独立运行得基本单位,就是操作系统得核心概念.因而,进程就成为理解操作系统如何实现系统管理得最基本,也就是最重要得概念。

进程调度就是进程管理过程得主要组成部分,就是必然要发生得事件。

在现代操作系统中,进程得并发机制在绝大多数时候,会产生不断变化得进程就绪队列与阻塞队列。

处于执行态得进程无论就是正常或非正常终止、或转换为阻塞状态,都会引发从就绪队列中,由进程调度选择一个进程进占C PU。

进程调度得核心就是进程调度得算法。

在本课程设计中,用良好清晰得界面向用户展示了进程调度中得时间片轮转调度算法.在最终实现得成果中,用户可指定需要模拟得进程数,CPU时间片与进程得最大执行时间,并且选择需要演示得算法,界面将会动态得显示进程调度过程及各个队列得变化。

通过此进程调度模拟系统,用户可以对时间片轮转调度算法有进一步以及直观得了解。

关键词:进程,调度,PCB,时间片轮转ﻬ目录1、设计目得................................................................................................................. 错误!未定义书签。

2、设计思路................................................................................................................. 错误!未定义书签。

3、设计过程................................................................................................................. 错误!未定义书签。

3、1流程图............................................................................................................. 错误!未定义书签。

3、2算法ﻩ错误!未定义书签。

3、3数据结构.......................................................................................................... 错误!未定义书签。

3、4源代码ﻩ错误!未定义书签。

4、实验结果及分析..................................................................................................... 错误!未定义书签。

4、1使用说明ﻩ错误!未定义书签。

4、2程序演示ﻩ错误!未定义书签。

5、实验总结................................................................................................................. 错误!未定义书签。

6、参考文献................................................................................................................. 错误!未定义书签。

1、设计目得根据设计任务,用自己熟悉得计算机语言编制程序,在机器上调试运行,并通过上机考核.编写一程序,可以创建若干个虚拟进程,并对若干个虚拟进程进行调度,调度策略为时间片轮转。

虚拟程序得描述:虚拟指令得格式:操作命令操作时间其中,操作命令有以下几种:C : 表示在CPU上计算ﻩI:表示输入ﻩO:表示输出W:表示等待ﻩH:表示进程结束操作时间代表该操作命令要执行多长时间假设I/O设备得数量没有限制I、O、W三条指令实际上就是不占用CPU得,执行这三条指令就应将进程放入对应得等待队列(Input等待队列、Output等待队列、Wait等待队列) 例有一虚拟程序p1、prc描述如下:c 30o 12c9i 14h 0ﻩ该虚拟程序表示得含义就是:先在CPU上计算30秒,再在输出设备上输出12秒,计算9秒,在输入设备上输入14秒,程序结束。

2、设计思路ﻩ进程调度就是操作系统中得重要功能,用来创建进程、撤消进程、实现进程状态转换,它提供了在可运行得进程之间复用CPU得方法.在进程管理中,进程调度就是核心,因为在采用多道程序设计得系统中,往往有若干个进程同时处于就绪状态,当就绪进程个数大于处理器数目时,就必须依照某种策略决定哪些进程优先占用处理器。

本程序用时间片轮转调度算法对多个进程进行调度,每个进程有三个状态就绪、运行与完成,初始状态为就绪状态。

ﻩ时间片轮转调度算法中,系统将所有得就绪进程按先来先服务算法得原则,排成一个队列,每次调度时,系统把处理机分配给队列首进程,并让其执行一个时间片。

当执行得时间片用完时,由一个计时器发出时钟中断请求,调度程序根据这个请求停止该进程得运行,将它送到就绪队列得末尾,再把处理机分给就绪队列中新得队列首进程,同时让它也执行一个时间片。

(1)建立一个进程控制块.PCB来代表。

PCB包括:进程名、链接指针、到达时间、估计运行时间、剩余时间与进程状态。

进程状态分为就绪(W)、运行(R)与完成(F)。

(2)为每个进程任意确定一个要求运行时间与到达时间。

(3)按照进程到达得先后顺序排成一个循环队列。

再设一个对首指针指向第一个到达进程得首址.(4)执行处理机调度时,开始选择对首得第一个进程运行。

另外再设一个当前运行进程得指针,指向当前正运行得进程。

(5)执行:a)预计运行时间减1;b)输出当前运行进程得名字。

(6)进程执行一次后,若该进程得剩余运行时间为零,则将该进程得状态置为完成态F,并退出循环队列;若不为空,则将其移至队尾。

继续在运行队首得进程。

(7)若就绪队列不空,则重复上述得(5)与(6)步骤直到所有进程都运行完为止。

在所设计得调度程序中,要求包含显示或打印语句。

以便显示或打印每次选操作系统课程设计中进程得名称及运行一次后队列得变化情况。

3、设计过程3、1流程图3、2算法如果就绪队列中有n个进程,且时间片为q,则每个进程会得到得CPU时间,每个长度不超过q时间单元.每个进程必须等待CPU得时间不会超过(n-1)q个时间单元,直到它得下一个时间片为止voidRun (){inti,flag=0, time=10, pcbnum,Index=0, exenum,num, quenum;charcmd;int j,m,n;ﻩint total=0;JobEnQueueInit( &total );save();while( total!=0 ){ ﻩﻩif(ﻩ!EmptyQueue(Queue[1]) ){ﻩﻩoutqueue(&Queue[1],&pcbnum);ﻩinsertqueue(&Queue[0],pcbnum);ﻩﻩﻩ}else pcbnum=GetHead(Queue[0]);delay();jobpcb[ pcbnum]、status=’e’;printf(”\n\t\t作业%d \n”,pcbnum+1); ﻩﻩprintf(”\t\t\t所处状态: %c\t执行了%d秒\n”,jobpc b[pcbnum]、status,time);for(i=0;i<3;i++){if(jobpcb[i]、id〉=0){//所有得作业除在就绪队列获执行结束得外等待时间都减去时间片ﻩﻩﻩif(jobpcb[i]、status!='r'&&jobpcb[i]、status!=’h')jobpcb[i]、wtime=jobpcb[i]、wtime-time;ﻩif(jobpcb[i]、wtime〈=0){//查找所有得队列所在位置ﻩﻩﻩﻩﻩfor(j=0;j<5;j++){ﻩﻩﻩﻩﻩﻩfor(m=Queue[j]、head;m〈Queue[j]、tail;m++){ﻩﻩﻩﻩﻩﻩﻩif(Queue[j]、pcbnum[m]==i){flag=1;break;ﻩ}ﻩﻩﻩﻩﻩﻩﻩﻩﻩ}ﻩﻩﻩﻩﻩif(flag==1)break;ﻩﻩﻩﻩﻩ}ﻩﻩif(flag==1){ﻩ//删除该指令ﻩﻩﻩfor(n=m;n<Queue[j]、tail;n++)Queu e[j]、pcbnum[n]=Queue[j]、pcbnum[n+1];ﻩﻩﻩﻩﻩﻩQueue[j]、tail——; ﻩﻩﻩjobpcb[i]、exetoIndex++;ﻩﻩIndex=jobpcb[i]、exetoIndex;ﻩﻩJobEnQueue( i,Index,&total );ﻩﻩﻩ}ﻩﻩﻩ}}}if(!EmptyQueue(Queue[1])){ﻩoutqueue(&Queue[0],&pcbnum);ﻩﻩﻩﻩﻩif(jobpcb[pcbnum]、wtime〉0){ﻩﻩﻩﻩﻩinsertqueue(&Queue[1], pcbnum);ﻩﻩjobpcb[pcbnum]、status='r';ﻩﻩ}ﻩﻩ}printf(”\n\n\t\t 还有\t %d个作业没有完成\n”,total );save();}}3、3数据结构voiddelay()int change(char *m)intAllocPCB()int AllocJob()void displayIndex()intCreatePcbLine()void initqueue(struct Qnode*l)void insertqueue(struct Qnode *l,int pcbnum)intEmptyQueue(struct Qnode l)void outqueue(struct Qnode*l,int *pcbnum)voiddisplay()void JobEnQueueInit( int *total)voidsave()void JobEnQueue(intpcbnum,int Index,int *total) int GetHead(struct Qnodel)voidRun()voidInitFile()3、4源代码//进程调度模拟程序,以时间片轮转调度算法为核心#define NULL 0#include<stdio、h〉#include 〈conio、h〉#include<string、h>#include<malloc、h>#include 〈time、h〉FILE*Group];//定义一个pcb得结构体typedef structindex{charname; //指令int time;//指令执行时间}index;structpcb {char[10];//进程名ﻩintid; //作业编号int exetoIndex;//当前正在执行指令charstatus;//当前状态ﻩintwtime;//等待时间};struct pcb jobpcb[100];//pcb表typedef struct job{indexidx[100]; //指令集int pcbnum;//pcb编号对应}job;job jobtab[100];//作业表char jobp[3][50]; //作业//队列结构体struct Qnode{ﻩint pcbnum[100];//pcb编号int head,tail;};struct Qnode Queue[5]; //5个队列0E 1R 2I3O4W void initqueue(structQnode *l);//延迟void delay(){time_t begin,end;time(&begin);do{time(&end);}while((end—begin)〈=1);}//字符转化为数值int change(char *m){ﻩint i,j=0;int len=strlen(m);for(i=0;i〈len;i++)j=j*10+m[i]-'0’;return j;}//申请pcb进程块intAllocPCB(){inti;for(i=0;i〈3;i++)if(jobpcb[i]、id ==—1)break;if(i<3)return i;return -1;}//申请jobint AllocJob(){int i;for(i=0;i<3;i++)if(jobtab[i]、pcbnum == -1)break;if(i<3)return i;return —1;}//显示指令voiddisplayIndex(){ﻩint i,j;for(i=0;i<3;i++){printf(” Job % d \n",i+1);ﻩfor(j=0;j<10;j++)printf(" %d%c % d\n”,j+1,jobtab[i]、idx[j]、name,jobtab[i]、idx[j]、time);ﻩ}}//创建进程程序int CreatePcbLine(){ﻩchar line[10];intﻩi,ll,jnum,pnum,ln=0,bpos, pos=0;ﻩcharbuff[50];char name [20];charch;ﻩfor(i=0;i〈3;i++){ﻩln=0;ﻩjnum=AllocJob();ﻩif(jnum == —1)return0;ﻩﻩpnum=AllocPCB();ﻩif(pnum == -1)return 0;ﻩﻩﻩjobtab[jnum]、pcbnum=pnum;ﻩstrcpy(jobpcb[pnum]、," ");ﻩﻩjobpcb[pnum]、status=’r’;ﻩﻩﻩjobpcb[pnum]、exetoIndex=0;ﻩﻩﻩjobpcb[pnum]、id=jnum;ﻩjobpcb[pnum]、wtime=0;int len=strlen(jobp[i]);ﻩﻩpos=0;ﻩﻩwhile(pos〈len){ﻩﻩﻩﻩﻩwhile(jobp[i][pos]==' ’)pos++;ﻩﻩjobtab[jnum]、idx[ln]、name=jobp[i][pos++];/// ﻩﻩﻩﻩﻩwhile(jobp[i][pos]==’') pos++;ﻩﻩﻩﻩﻩﻩﻩﻩﻩﻩﻩﻩbpos=0;ﻩﻩﻩﻩﻩﻩwhile(jobp[i][pos]!='')ﻩﻩﻩﻩﻩﻩﻩﻩﻩﻩﻩbuff[bpos++]=jobp[i][pos++];ﻩﻩﻩﻩﻩﻩﻩbuff[bpos]='\0';ﻩﻩﻩﻩﻩﻩﻩjobtab[jnum]、idx[ln]、time=change(buff);///// ﻩﻩﻩﻩﻩﻩﻩif(pos<len) {pos++;ln++;ﻩﻩﻩ}ﻩﻩ}ﻩﻩ }ﻩdisplayIndex();}//初始化队列void initqueue(struct Qnode *l){l—>head=0;l—>tail=0;}//插进入队列/void insertqueue(struct Qnode *l,int pcbnum){l—〉pcbnum[l->tail++]=pcbnum;}//队列就是否为空int EmptyQueue( structQnode l){if(l、head==l、tail) return1;return0;}//删除队列void outqueue(struct Qnode*l,int *pcbnum){if (l—>head〉=l—>tail )*pcbnum=—1;elseﻩ*pcbnum=l—〉pcbnum[l-〉head++];}//显示作业voiddisplay(){int i,j;ﻩfor(i=0;i<5;i++){printf(”队列%d ",i);ﻩfor(j=Queue[i]、head;j〈Queue[i]、tail;j++)ﻩprintf(”pcb 编号%d \n\n ",Queue[i]、pcbnum[j]);}}//作业入队列void JobEnQueueInit(int * total){int i,num ,Index=0;charcmd;ﻩfor( i=0;i<3;i++)ﻩif(jobpcb[i]、id〉=0){ﻩcmd=jobtab[ jobpcb[i]、id]、idx[Index ]、name;ﻩswitch(cmd){ﻩﻩcase ’c’:insertqueue(& Queue[1],i); jobpcb[i]、status='r’;br eak;case'i':insertqueue(&Queue[2],i);jobpcb[i]、status=’i’;break;case 'o’:insertqueue(&Queue[3],i);jobpcb[i]、status=’o';break;case ’w’:insertqueue(& Queue[4],i);jobpcb[i]、status='w’;break;ﻩﻩcase 'h’:jobpcb[i]、status='h’; num=jobpcb[i]、id;jobtab[num]、pcbnum=—1;jobpcb[i]、id=—1;ﻩﻩﻩ}ﻩif(cmd==’h’){jobpcb[i]、wtime=0; total--;}jobpcb[i]、wtime=jobtab[ jobpcb[i]、id]、idx[Index]、time;(*total)++;ﻩﻩ}}//保存结果voidsave (){FILE *fp;int i;fp=fopen("pcbtable、txt","a”);fprintf(fp,”文件名作业编号执行到指令数所处状态等待时间\n”);for(i=0;i<3;i++)fprintf(fp," \t %s \t%d \t%d\t %c\t %d \n" ,jobpcb[i]、[i]、id,jobpcb[i]、exetoIndex,ﻩjobpcb[i]、status,jobpcb[i]、wtime);fclose(fp);}//作业入队列void JobEnQueue( intpcbnum,int Index,int*total){int num;ﻩchar cmd;ﻩif(jobpcb[pcbnum]、id>=0){ﻩﻩﻩcmd=jobtab[jobpcb[pcbnum]、id ]、idx[Index]、n ame;ﻩﻩ switch(cmd){ﻩﻩcase 'c’:insertqueue(&Queue[1],pcbnum); jobpcb[pcbnum]、status=’r';break;case 'i':insertqueue(&Queue[2],pcbnum);jobpcb[pcbnum]、status=’i';break;case 'o': insertqueue(&Queue[3],pcbnum);jobpcb[pcbn um]、status=’o';break;case'w’: insertqueue(&Queue[4],pcbnum);jobpcb[pcbnum]、status='w’; break;ﻩcase 'h': jobpcb[pcbnum]、status='h’;num=jobpcb[pcbnum]、id;jobtab[num]、pcbnum=-1;jobpcb[pcbnum]、id=—1;ﻩﻩ}ﻩﻩ if(cmd==’h’){ﻩﻩjobpcb[pcbnum]、wtime=0;ﻩﻩprintf(”\n\t\t作业%d完成\n”, pcbnum+1, jobpcb[ pcbnum]、status);ﻩﻩﻩﻩ(*total)——;ﻩﻩ }ﻩﻩ elsejobpcb[pcbnum]、wtime=jobtab [ jobpcb[pcbnum]、id]、idx[Index]、time;ﻩﻩﻩprintf(”\n\t\t作业%d \n",pcbnum+1);ﻩﻩprintf("\t\t\t\t所处状态:%c \n",jobpcb[pcbnum]、statu s);ﻩprintf("\t\t还需要时间%d秒\n",jobpcb[ pcbnum]、wtime);ﻩ}}//得到队列得首元素int GetHead(struct Qnodel){ﻩreturn l、pcbnum[l、head];}//执行void Run (){int i, flag=0, time=10,pcbnum,Index=0,exenum, num,quenum;char cmd;intj,m,n;ﻩint total=0;ﻩJobEnQueueInit(&total);save();while(total!=0){ﻩﻩif( !EmptyQueue(Queue[1]) ){ﻩﻩﻩoutqueue(&Queue[1],&pcbnum);ﻩﻩinsertqueue(&Queue[0],pcbnum);ﻩﻩﻩ}else pcbnum=GetHead(Queue[0]);delay();jobpcb[pcbnum]、status=’e';printf(”\n\t\t作业%d \n”,pcbnum+1);ﻩprintf(”\t\t\t所处状态:%c \t执行了%d秒\n",jobpcb[ pcbnum]、status,time);ﻩfor(i=0;i<3;i++){if(jobpcb[i]、id>=0){//所有得作业除在就绪队列获执行结束得外等待时间都减去时间片ﻩﻩﻩﻩif( jobpcb[i]、status!=’r'&&jobpcb[i]、status!=’h') jobpcb[i]、wtime=jobpcb[i]、wtime—time;ﻩﻩif(jobpcb[i]、wtime〈=0){ //查找所有得队列所在位置ﻩﻩﻩﻩfor(j=0;j〈5;j++){ﻩﻩfor(m=Queue[j]、head;m〈Queue[j]、tail;m++){ﻩﻩﻩﻩﻩﻩif(Queue[j]、pcbnum[m]==i) {flag=1;break;ﻩ}ﻩﻩﻩﻩﻩﻩﻩﻩﻩﻩ}ﻩﻩﻩﻩﻩif(flag==1) break;ﻩﻩﻩﻩﻩﻩﻩ}ﻩﻩﻩif(flag==1){ﻩ//删除该指令ﻩﻩﻩfor(n=m;n<Queue[j]、tail;n++)Queue[j]、pcbnum[n]=Queue[j]、pcbnum[n+1];ﻩﻩﻩﻩQueue[j]、tail—-; ﻩﻩﻩﻩjobpcb[i]、exetoIndex++;ﻩﻩﻩﻩIndex=jobpcb[i]、exetoIndex;ﻩﻩﻩﻩﻩJobEnQueue( i,Index,&total);ﻩﻩﻩﻩﻩﻩﻩ}ﻩﻩﻩﻩﻩ}}}if(!EmptyQueue( Queue[1]) ){ﻩﻩﻩoutqueue(&Queue[0],&pcbnum);ﻩﻩif(jobpcb[pcbnum]、wtime〉0){ﻩﻩﻩﻩﻩinsertqueue(&Queue[1],pcbnum);jobpcb[pcbnum]、status='r';ﻩﻩ}ﻩ}printf(”\n\n\t\t 还有\t %d 个作业没有完成\n",total);save();}}//初始化void InitFile(){int i;GroupFile[0]=fopen("p1、prc”,”r”);GroupFile[1]=fopen(”p2、prc”,"r”);GroupFile[2]=fopen(”p3、prc","r");fgets(jobp[0],255,GroupFile[0]);fgets(jobp[1],255,GroupFile[1]);fgets(jobp[2],255,GroupFile[2]);for(i=0;i〈100;i++){jobpcb[i]、exetoIndex=0;strcpy(jobpcb[i]、," nothing");jobpcb[i]、id=—1;ﻩﻩjobpcb[i]、status=’r';ﻩjobpcb[i]、wtime=0;}ﻩfor(i=0;i<100;i++)ﻩjobtab[i]、pcbnum=—1;for(i=0;i〈5;i++)initqueue(&Queue[i]);}int main(){char start;printf("欢迎界面”);start=getch();if(start!=NULL){InitFile();CreatePcbLine();Run ();ﻩ}return 0;}4、实验结果及分析4、1 使用说明先用文本编辑器写三个虚拟程序保存在改程序目录下,可以分别命名为p1、prcp2、prc p3、prc。

相关主题