程序下载链接:https://download.csdn.net/download/m0_56241309/86945709

进程调度模拟

摘要:进程调度是操作系统中必不可少的一种调度,在3中OS中都无一例外地配置了进程调度。此外,它也是对系统性能影响最大的一种处理机调度,在操作系统中具有十分重要的地位。本次模拟,旨在全方位地了解、掌握、运用各种调度算法,包括从本质上理解各种调度方法的实现方式、各种调度算法使用的数据结构、各种调度方法使用的函数模块、各种调度算法的函数调用情况等等。针对本次模拟,任务中包括了四种在操作系统中较为重要的调度方法,因此最先考虑的是如何依次实现各种调度方法,包括对各种算法的系统功能设计、模块、流程设计、数据结构设计等等。之后再依调整各种算法内部的数据结构以及符号名,消除各个算法之间的冲突,主要是命名冲突引起的函数调用冲突、变量使用冲突。在对各种算法进行调整后,将其整合到一个主体呈现出switch结构的MAIN()函数中。经过本次模拟,总体上较为完整地实现了对N个进程采用4个进程调度算法的目的(四选一),但在各种算法的内部仍然存在许多值得优化的地方,例如在MAIN()函数中涉及一个整体的数据结构即可避免在每一个算法中都对数据结构进行大体上重复的定义,诸如此类的可以优化的地方依然存在,因此本次模拟并不是最终目的,后继学习过程中对操作系统调度算法的更加熟练的掌握将更加有助于我们对于计算机操作系统的理解与掌握。

关键词:操作系统;进程调度;课程设计

1 设计任务

1.1 设计目的

在多道程序环境下,内存中存在许多进程,其数目往往多余处理及的数量。这就要求操作系统能够按照某种算法动态地将处理机分配给处于就绪状态的进程。对于一个大型的操作系统而言,其运行是的性能,诸如系统吞吐量、资源利用率、作业周转时间、响应的及时性等,在很大程度上都取决于处理机调度性能的好坏。如若处理机调度存在问题,则会非常容易导致系统出现死锁,进程将无法向前推进。次模拟选题为进程调度模拟,旨在了解、认识、掌握调度算法这一处理机调度最为核心的部分,实现对多个进程实现不同的调度方法,加深对操作系统调度方法的掌握,进而更加深层次地认识操作系统。

1.2 设计内容

1.2.1设计要求

(1)对N个进程分别采用四种进程调度算法(轮转调度、静态优先级调度、动态优先级调度、最短进程优先调度)执行调度模拟。

(2)每个用来标识进程的进程表项(进程控制块 PCB)可用结构体来描述,包括以下字段(具体字段及数量可根据需要自行定义,此处仅供参考):

(a)进程标识数 ID。

(b) 进程优先数 PRIORITY,并规定优先数越大的进程,其优先权越高。

(c) 进程运行所需CPU总时间片数ALLTIME,已占用 CPU 时间片数 CPUTIME。当进程运行完毕时,ALLTIME 变为 0。

(d) 进程的待阻塞时间片数 STARTBLOCK,表示当进程再运行 STARTBLOCK个时间片后,进程将进入阻塞状态。

(e) 进程被阻塞的时间片数 BLOCKTIME ,表示已阻塞的进程再等待 BLOCKTIME 个时间片后,将转换成就绪状态。

(f) 进程状态 STATE。

(g) 队列指针 NEXT,用来将 PCB 排成队列。

(3)进程数量要求可以指定任意数量,每个进程运行所需的CPU时间数要求可以指定任意数量或随机生成。

(4)静态优先级调度,每个进程的优先级要求可以任意指定或随机生成。

(5)动态优先级调度原则:进程在就绪队列中呆一个时间片,优先数增加 1;进程每运行一个时间片,优先数减 3(这一规则主要用于动态优先级调度算法)。

(6)最短进程优先中的进程长度根据剩余所需CPU时间片数动态计算。

(7)为了观察每个进程的调度过程,程序应将每个时间片内的进程的情况显示出来,包括正在运行的进程,处于就绪队列中的进程和处于阻塞队列中的进程。

(8)要求在linux ubuntu环境下使用c/c++编写。

1.2.2部分调整

(1)本次模拟首先对四种调度方法分别进行了实现,因此各种调度算法内部的PCB数据结构存在着一定程度上的差别,但对于每种调度算法均采用了设计要求中规定的变量名程。

(2)后期对各种调度算法进行整合时,出现了变量命名之间的冲突,因此部分算法内部的变量命名出现了诸如RR(轮转调度)、DP(动态优先级)、SP(静态优先级)、SJF(最短进程优先)字样的前缀。

(3)在本次模拟中,提供了四种调度方法供用户选择,以此实现对N种进程采用4种不同的调度方法。

2 总体设计

2.1 总体结构

图2-1 模拟进程调度演示系统功能模块图

2.2 开发环境

Linux操作系统、VMware虚拟机、开发语言c/c++、HUAWEI MATEBOOK XPRO笔记本

3 算法设计

3.1轮转调度算法

   在早期的时间片轮转法中,系统将所有的就绪进程按先来先服务的原则,排成一个队列,每次调度时,把CPU分配给队首进程,并令其执行一个时间片。如果就绪队列上存在N个进程,那么每个进程每次大约可获得1/N的处理机时间。

   如图2-1功能模块图所示,在轮转调度方法种,需要对PCB块进行数据结构设计,并且完成对队列结点定义模块、队列初始化模块、进程队列创建模块、进程插入模块、进程输出模块、RR算法模块的实现。

具体流程如下:(虚线仅代表在程序编写时逻辑上的先后顺序,实现代表模块之间存在调用关系)

其中,RR轮转调度算法中设计的PCB数据结构如下:

3.2静态优先级调度算法

优先级调度算法中的静态优先级调度在一开始便根据各个进程的PRIORITY确定下来进程的顺序,优先级在整个运行期间保持不变。一般而言,确定进程优先级大小的依据主要有进程类型、进程对资源的需求、用户要求。静态优先级的调度方法简单易行,但不够精确,会出现进程长时间无法被调度的现象。

如图2-1功能模块图所示,在静态优先级调度算法种,除了对PCB数据块进行设计,还需要完成对进程队列创建模块、SP算法等模块的实现。

具体流程如下:

其中,SP静态优先级调度算法中设计的PCB数据结构如下:

3.3动态优先级调度算法

      动态优先级调度算法是指在进程创建之初,赋予进程一个暂时的优先级别,随着进程的推进,进程的优先级别会随之改变,本次模拟中采用的规则为: 进程在就绪队列中呆一个时间片,优先数增加 1;进程每运行一个时间片,优先数减 3。这样的调度方法可以较为公平地实现进程间处理机的分配,避免了一个长期进程长期垄断处理机的现象。

   如图2-1功能模块图所示,在动态优先级调度算法中,需对PCB数据块进行设计,此外还需完成对进程队列创建模块、DP算法等模块的实现。

具体流程如下:

其中,DP动态优先级调度算法中设计的PCB数据结构如下:

3.4最短进程优先调度算法

      最短进程优先调度方法以进程的长短来计算优先级,本次模拟中采用进程所需的CPU时间片数来作为优先级的判定依据,即每个进程的剩余ALLTIME时间数。最短进程优先调度每次从队列中取出时间最短的进程运行。最短进程优先调度算法的缺点在于,必须预先知道进程运行所需时间、对ALLTIME较长的进程并不友好、当采用FCFS调度方法时,无法实现人机交互。此外,最短进程优先调度方法无法考虑到进程的紧急程度,因此无法保证紧急的作业得到及时处理。

如图2-1功能模块图所示,最短进程优先调度算法中,除对PCB数据块进行设计以外,还需实现进程队列创建模块、调度结果输出模块、SJF算法等模块。

具体流程如下:

依旧使用数组的形式来存放进程,便于实现依据次序标号对进程的直接查找以及调度

其中,SJF最短进程优先调度算法中设计的PCB数据结构如下:

4 系统实现

4.1 用户输入模块实现(部分主函数的实现)

#include"SJF.h"#include"SP.h"#include"RR.h"#include"DP.h"int main(){  printf("【本次模拟除进程名以外的所有输入均为整数】\n\n\n");int B;printf("请选择PRIORITY、ALLTIME的生成方式:\n【1】手动输入\n【2】随机生成\n");scanf("%d",&B);int A;printf("\n");printf("请选择调度方法(输入对应序号即可)\n");Q:printf("【1】轮转调度\n【2】最短进程优先调度\n【3】静态优先级调度\n【4】动态优先级调度\n");scanf("%d",&A);if (A>4){printf("输入有误,请重新输入\n");goto Q;}}

4.2 轮转调度模块实现

4.2.1 PCB数据结构设计

typedef struct pcb          //定义进程控制块{char ID[MaxNum];        //进程号int Arrive_Time;        //进程到达时间,用以排序int ALLTIME;            //进程运行所需总时间int WHLOLETIME;         //固定运行时间int FinishTime;         //完成时间double RUN_AROUND_TIME; //周转时间double WeightWholeTime; //带权周转时间char STATE;             //进程状态struct pcb *NEXT;}RRPCB;

4.2.2队列结点定义模块

typedef struct   //定义队列以及头结点尾结点{RRPCB *front,*rear;}queue;

4.2.3队列初始化模块

queue *Init()  //初始化队列{queue *HEAD;HEAD=(queue*)malloc(sizeof(queue));HEAD->front=NULL;HEAD->rear=NULL;return HEAD;}

4.2.4进程队列创建模块

queue *CreatQueue(queue *head,int M,int B)   //创建进程队列{char c[MaxNum];char s='R';int a,r,i;if (B==1){for(i=1;i<=M;i++){printf("请输入第%d个进程的进程名:\n",i);getchar();cin.get(c,MaxNum);printf("请输入第%d个进程的到达时间:\n",i);scanf("%d",&a);printf("请输入第%d个进程的服务时间:\n",i);scanf("%d",&r);head=Insert(head,c,a,r,s);printf("\n");}}else{for(i=1;i<=M;i++){printf("请输入第%d个进程的进程名:\n",i);getchar();cin.get(c,MaxNum);printf("请输入第%d个进程的到达时间:\n",i);scanf("%d",&a);r=(int)(rand()%12);//r即进程所需总时长head=Insert(head,c,a,r,s);printf("\n");}}return head;}

4.2.5进程插入模块

queue *Insert(queue *head,char c[MaxNum],int a,int r,char s)  //将进程插入队列,每次取出队首的进程运行{RRPCB *p;p=(RRPCB *)malloc(sizeof(RRPCB));strcpy(p->ID,c);p->Arrive_Time=a;p->ALLTIME=r;p->WHLOLETIME=r;p->STATE=s;p->NEXT=NULL;if(Empty(head))head->front=head->rear=p;else{head->rear->NEXT=p;head->rear=p;}return head;}

4.2.6进程输出模块

void print(queue *head)  //输出进程{RRPCB *p;p=head->front;if(!p)printf("时间片轮转调度队列为空!\n");while(p){printf("ID=%s   Arrvie_Time=%d   ALLTIME=%d   STATE=%c",p->ID,p->Arrive_Time,p->ALLTIME,p->STATE);printf("\n");p=p->NEXT;}}

4.2.7RR(轮转调度)算法模块

void RR(queue *head,int Time_Slice){int t=head->front->Arrive_Time, lt=head->rear->Arrive_Time;if(head->front->ALLTIME<Time_Slice)t=t+head->front->ALLTIME;elset=t+Time_Slice;//队列为空则无法调度while(!Empty(head)){RRPCB *p1,*p2;printf("\n时刻   进程   状态\n");//当前运行的时间小于最后一个进程到达时间while(t<lt){p1=head->front;printf("%2d      %s",t,p1->ID);p1->ALLTIME=p1->ALLTIME-Time_Slice;//判断在进程所需要的ALLTIME内是否可以完成,用ALLTIME-CPUTIME判断//1.运行时间小于0,删除队首进程if(p1->ALLTIME<=0){p1->STATE='C';printf("       %c\n",p1->STATE);p1->FinishTime=t;p1->RUN_AROUND_TIME=p1->FinishTime-p1->Arrive_Time;p1->WeightWholeTime=p1->RUN_AROUND_TIME/p1->WHLOLETIME;SumWT+=p1->RUN_AROUND_TIME;SumWWT+=p1->WeightWholeTime;printf("=========================================================\n");printf("时刻%2d进程%s运行结束,进程%s周转时间=%5.2f,带权周转时间=%5.2f\n",t,p1->ID,p1->ID,p1->RUN_AROUND_TIME,p1->WeightWholeTime);printf("=========================================================\n");head->front=p1->NEXT;free(p1);}//2.运行时间大于0,继续排队else{printf("        %c\n",p1->STATE);p2=p1->NEXT;while(p2->NEXT && p2->Arrive_Time != t){p2=p2->NEXT;}//没有新的进程到达时//1.保持队首进程//2.队首进程后移if(p2->Arrive_Time != t){RRPCB *p3=p1,*p4=NULL;while(p3->NEXT && p3->Arrive_Time<t){p4=p3;p3=p3->NEXT;}if(p3->Arrive_Time>t){if(p4!=p1)   //p1插在p4后,头节点p1->NEXT{head->front=p1->NEXT;p1->NEXT=p4->NEXT;p4->NEXT=p1;}elsep4=p3=p2=NULL;}elsep4=p3=p2=NULL;}//新的进程到达//队首进程插入在新进程之后,指针更新else{head->front=p1->NEXT;p1->NEXT=p2->NEXT;p2->NEXT=p1;}}//更新时间if(head->front->ALLTIME<Time_Slice)t=t+head->front->ALLTIME;elset=t+Time_Slice;}//ALLTIME大于最后一个进程到达的时间while(t>=lt){p1=head->front;printf("%2d      %s",t,p1->ID);p1->ALLTIME=p1->ALLTIME-Time_Slice;//1.运行时间小于0,删除队首进程if(p1->ALLTIME<=0){p1->STATE='C';printf("       %c\n",p1->STATE);p1->FinishTime=t;p1->RUN_AROUND_TIME=p1->FinishTime-p1->Arrive_Time;p1->WeightWholeTime=p1->RUN_AROUND_TIME/p1->WHLOLETIME;SumWT+=p1->RUN_AROUND_TIME;SumWWT+=p1->WeightWholeTime;printf("=========================================================\n");printf("时刻%2d进程%s运行结束,进程%s周转时间=%5.2f,带权周转时间=%5.2f\n",t,p1->ID,p1->ID,p1->RUN_AROUND_TIME,p1->WeightWholeTime);printf("=========================================================\n");//printf("时刻%2d进程%s运行结束",t,p1->pname);head->front=p1->NEXT;free(p1);}//2.运行时间大于0,进程插入队列末else{printf("       %c\n",p1->STATE);//队列中只有一个进程无需更改if(!p1->NEXT)head->front=p1;//队列中的进程数大于1时else{head->front=p1->NEXT;head->rear->NEXT=p1;head->rear=p1;p1->NEXT=NULL;}}//更新时间if(Empty(head))return;else{if(head->front->ALLTIME<Time_Slice)t=t+head->front->ALLTIME;elset=t+Time_Slice;}}}}

4.3 静态优先级调度模块实现

4.3.1PCB数据结构设计模块

struct PCB{char PNAME[20];int PRIORITY;int ALLTIME;int CPUTIME;char STATE;struct PCB* NEXT;int num;};

4.3.2进程队列创建模块

struct PCB *processes, *Temp_Node;//Temp_Node作为临时节点来创建链表processes = Temp_Node = (struct PCB*)malloc(sizeof(struct PCB));if (B==1){for (int i = 1; i <= N; ++i){struct PCB *p = (struct PCB*)malloc(sizeof(struct PCB));printf("进程号No.%d:\n", i);printf("输入进程名:");scanf("%s", p->PNAME);printf("输入进程优先数:");scanf("%d", &p->PRIORITY);printf("输入进程所需总时间:");scanf("%d", &p->ALLTIME);p->CPUTIME = 0;p->STATE = 'W';p->NEXT = NULL;Temp_Node->NEXT = p;Temp_Node = p;p->num=p->ALLTIME;printf("\n\n");}}else{for (int i = 1; i <= N; ++i){struct PCB *p = (struct PCB*)malloc(sizeof(struct PCB));printf("进程号No.%d:\n", i);printf("输入进程名:");scanf("%s", p->PNAME);p->PRIORITY=(int)(rand()%12);p->ALLTIME=(int)(rand()%12);p->num=p->ALLTIME;p->CPUTIME = 0;p->STATE = 'W';p->NEXT = NULL;Temp_Node->NEXT = p;Temp_Node = p;printf("\n\n");}}

4.3.3SP(静态优先级调度)算法模块

//processes作为头结点来存储链表processes = processes->NEXT;int Present_Time = 0;struct PCB *P_INORDER = processes;while (1){  ++Present_Time;Temp_Node = processes;//对链表按照优先数排序//P_INORDER用来存放排序后的链表P_INORDER = SortList(P_INORDER);printf("===============================================\n");printf("当前时刻为: %d\n", Present_Time-1);printf("===============================================\n");printf("当前正在运行的进程是:%s\n", P_INORDER->PNAME);P_INORDER->STATE = 'R';P_INORDER->num--;P_INORDER->CPUTIME++;printf("PNAME    STATE    PRIORITY    ALLTIME    CPUTIME\n");printf("  %s        %c          %d          %d          %d\n", P_INORDER->PNAME, P_INORDER->STATE, P_INORDER->PRIORITY, P_INORDER->num, P_INORDER->CPUTIME);Temp_Node->STATE = 'W';printf("当前就绪状态的队列为:\n\n");//Temp_Node指向已经排序的队列Temp_Node = P_INORDER->NEXT;while (Temp_Node != NULL){  printf("PNAME    STATE    PRIORITY    ALLTIME    CPUTIME\n");printf("  %s        %c          %d          %d          %d\n", Temp_Node->PNAME, Temp_Node->STATE, Temp_Node->PRIORITY, Temp_Node->ALLTIME, Temp_Node->CPUTIME);Temp_Node = Temp_Node->NEXT;}//Temp_Node指向已经排序的链表Temp_Node = P_INORDER;struct PCB *PRE_TEMPNODE;PRE_TEMPNODE = NULL; //PRE_TEMPNODE指向Temp_Node的前一个节点while (Temp_Node != NULL){if (Temp_Node->ALLTIME == Temp_Node->CPUTIME){if (PRE_TEMPNODE == NULL){Temp_Node = P_INORDER->NEXT;P_INORDER = Temp_Node;}elsePRE_TEMPNODE->NEXT = Temp_Node->NEXT;}PRE_TEMPNODE = Temp_Node;Temp_Node = Temp_Node->NEXT;}}}struct PCB* SortList(PCB* HL){struct PCB* SL;SL = (struct PCB*)malloc(sizeof(struct PCB));SL = NULL;struct PCB* r = HL;while (r != NULL){struct PCB* t = r->NEXT;struct PCB* cp = SL;struct PCB* PRE_TEMPNODE = NULL;while (cp != NULL){if (r->PRIORITY > cp->PRIORITY)break;else{PRE_TEMPNODE = cp;cp = cp->NEXT;}}if (PRE_TEMPNODE == NULL){r->NEXT = SL;SL = r;}else{r->NEXT = cp;PRE_TEMPNODE->NEXT = r;}r = t;}return SL;

4.4 动态优先级调度模块实现

4.4.1PCB数据结构设计模块

typedef struct{char ID;int PRIORITY;int CPUTIME;int ALLTIME;int STARTBLOCK;int BLOCKTIME;int STATE;//0-运行 1-阻塞 2-就绪 3-结束 4-未到达int Arrive_Time;int TIME;}PROCESS;

4.4.2进程队列创建模块

IntDI=0,DPTime_Slice,max,l,l1,time1,flag=0,total=0,server[10],sum=0,DPN=0;PROCESS pro[10];cout<<"本程序中状态代表如下"<<endl<<"【0】-运行  【1】-阻塞  【2】-就绪  【3】-结束  【4】-未到达"<<endl<<endl;if (B==1){cout<<"请输入进程数:";cin>>DPN;cout<<"请设置时间片长度:";cin>>DPTime_Slice;cout<<"请输入各进程初始状态:"<<endl;cout<<"ID  PRIORITY  Arrive_Time  ALLTIME  STARTBLOCK  BLOCKTIME"<<endl;for(DI=0;DI<DPN;DI++){//进程初始化pro[DI].CPUTIME=0;pro[DI].TIME=0;cin>>pro[DI].ID>>pro[DI].PRIORITY>>pro[DI].Arrive_Time;cin>>pro[DI].ALLTIME>>pro[DI].STARTBLOCK>>pro[DI].BLOCKTIME;server[DI]=pro[DI].ALLTIME;if(pro[DI].Arrive_Time==0) pro[DI].STATE=0;else pro[DI].STATE=4;}}else{cout<<"请输入进程数:";cin>>DPN;cout<<"请设置时间片长度:";cin>>DPTime_Slice;cout<<"请输入各进程初始状态:"<<endl;cout<<"ID   Arrive_Time   STARTBLOCK  BLOCKTIME"<<endl;for (int DI = 0; DI < DPN; DI++){pro[DI].CPUTIME=0;pro[DI].TIME=0;cin>>pro[DI].ID>>pro[DI].Arrive_Time;cin>>pro[DI].STARTBLOCK>>pro[DI].BLOCKTIME;pro[DI].PRIORITY=(int)(rand()%10);pro[DI].ALLTIME=(int)(rand()%10);server[DI]=pro[DI].ALLTIME;if(pro[DI].Arrive_Time==0) pro[DI].STATE=0;else pro[DI].STATE=4;}}

4.4.3DP(动态优先级调度)算法模块

do{cout<<endl<<"当前时刻为:"<<total;cout<<endl<<"========================各进程状态为======================"<<endl;cout<<"ID  PRIORITY  CPUTIME  ALLTIME  STARTBLOCK  BLOCKTIME  STATE"<<endl;for(DI=0;DI<DPN;DI++){cout<<pro[DI].ID<<"      "<<pro[DI].PRIORITY<<"        "<<pro[DI].CPUTIME<<"        ";cout<<pro[DI].ALLTIME<<"         "<<pro[DI].STARTBLOCK<<"           "<<pro[DI].BLOCKTIME<<"         "<<pro[DI].STATE;cout<<endl;}total+=DPTime_Slice;for(DI=0;DI<DPN;DI++){if(pro[DI].STATE==4&&pro[DI].Arrive_Time<total){pro[DI].STATE=1;}}for(DI=0;DI<DPN;DI++){time1=pro[DI].ALLTIME;if(pro[DI].STATE==0){if(pro[DI].ALLTIME<=DPTime_Slice){pro[DI].ALLTIME=0;pro[DI].STATE=3;pro[DI].TIME=total-DPTime_Slice+time1;}else{pro[DI].ALLTIME-=DPTime_Slice;pro[DI].STARTBLOCK--;if(pro[DI].STARTBLOCK==0){pro[DI].STATE=1;pro[DI].BLOCKTIME=time1;pro[DI].STARTBLOCK=time1;}pro[DI].PRIORITY-=3;pro[DI].TIME=total;}}if(pro[DI].STATE==1){pro[DI].BLOCKTIME--;if(pro[DI].BLOCKTIME==0) pro[DI].STATE=2;pro[DI].TIME=total;}if(pro[DI].STATE==2){pro[DI].PRIORITY++;pro[DI].TIME=total;}}max=-100;l1=-1;l=-1;for(DI=0;DI<DPN;DI++){if(pro[DI].PRIORITY>max&&(pro[DI].STATE==0||pro[DI].STATE==2)){l=DI;max=pro[DI].PRIORITY;}if(pro[DI].STATE==0) l1=DI;}if(l!=-1&&l!=l1) pro[l].STATE=0;if(l1!=-1) pro[l1].STATE=2;flag=0;for(DI=0;DI<DPN;DI++){if(pro[DI].STATE!=3){flag=1;break;}}if(flag==0) break;}while(1);cout<<endl<<"当前时刻:"<<total;cout<<endl<<"========================各进程状态为======================"<<endl;cout<<"ID  PRIORITY  CPUTIME  ALLTIME  STARTBLOCK  BLOCKTIME  STATE"<<endl;for(DI=0;DI<DPN;DI++){cout<<pro[DI].ID<<"      "<<pro[DI].PRIORITY<<"        "<<pro[DI].CPUTIME<<"        ";cout<<pro[DI].ALLTIME<<"         "<<pro[DI].STARTBLOCK<<"           "<<pro[DI].BLOCKTIME<<"         "<<pro[DI].STATE;cout<<endl;}cout<<endl<<"各进程运行结束!"<<endl;cout<<"进程号  到达时间  结束时间  周转时间  带权周转时间"<<endl;for(DI=0;DI<DPN;DI++){cout<<"  "<<pro[DI].ID<<"        "<<pro[DI].Arrive_Time<<"         "<<pro[DI].TIME<<"       "<<pro[DI].TIME-pro[DI].Arrive_Time<<"        "<<(float)(pro[DI].TIME-pro[DI].Arrive_Time)/server[DI]<<endl;sum+=pro[DI].TIME-pro[DI].Arrive_Time;}cout<<"平均周转时间为:"<<(float)sum/DPN<<endl;

4.5 最短进程优先调度模块实现

4.5.1PCB数据结构设计模块

 struct Process_struct{int  Number;                            //进程编号char Name[MaxNum];                      //进程名称int  ArrivalTime;                       //到达时间int  ServiceTime;                       //开始运行时间int  FinishTime;                        //运行结束时间int  SJF_ALLTIME;                       //运行时间int STATE;                              //调度标志int order;                              //运行次序double  WeightWholeTime;                //周转时间double AverageWT_SJF;                   //平均周转时间double AverageWWT_SJF;                  //平均带权周转时间}Process[MaxNum];

4.5.2进程队列创建模块

int PROCESSinput(int B)         //进程参数输入{int i;printf("请输入进程个数:\n");scanf("%d",&SJFPN);if (B==1){for(i=0;i<SJFPN;i++){printf("请输入第%d个进程名称:",i+1);scanf("%s",Process[i].Name);printf("请输入第%d个进程的到达时间:",i+1);scanf("%d",&Process[i].ArrivalTime);printf("请输入第%d个进程的ALLTIME:",i+1);scanf("%d",&Process[i].SJF_ALLTIME);Process[i].ServiceTime=0;Process[i].FinishTime=0;Process[i].WeightWholeTime=0;Process[i].order=0;Process[i].STATE=0;printf("\n");}}else{for(i=0;i<SJFPN;i++){printf("请输入第%d个进程名称:",i+1);scanf("%s",Process[i].Name);printf("请输入第%d个进程的到达时间:",i+1);scanf("%d",&Process[i].ArrivalTime);Process[i].SJF_ALLTIME=(int)(rand()%11);Process[i].ServiceTime=0;Process[i].FinishTime=0;Process[i].WeightWholeTime=0;Process[i].order=0;Process[i].STATE=0;printf("\n");}}return 0;}

4.5.3调度结果输出模块

int OUTCOME()   //调度结果输出{int i;float turn_round_time=0,f1,w=0;printf("      进程名称 到达时间 运行时间 开始时间 结束时间 执行顺序  周转时间  带权周转时间\n");for(i=0;i<SJFPN;i++){Process[i].WeightWholeTime=Process[i].FinishTime-Process[i].ArrivalTime;f1=Process[i].WeightWholeTime/Process[i].SJF_ALLTIME;turn_round_time+=Process[i].WeightWholeTime;w+=f1;printf("时刻%d :",Process[i].ServiceTime,Process[i].Name);printf("   %s       %d       %d         %d         %d         %d        %.2f        %.2f\n",Process[i].Name,Process[i].ArrivalTime,Process[i].SJF_ALLTIME,Process[i].ServiceTime,Process[i].FinishTime,Process[i].order,Process[i].WeightWholeTime,f1);}printf("平均周转时间=%.2f\n",turn_round_time/SJFPN);printf("带权平均周转时间=%.2f\n",w/SJFPN);return 0;}

4.5.4 SJF(最短进程优先调度)算法模块

int SJF(){              //短作业优先算法int temp_time=0;    //当期那时间int i=0,j;int PID_ORDERED,PRESENT_PNUMBER;      //进程编号,当前已执行进程个数float run_time;run_time=Process[i].SJF_ALLTIME;j=1;while((j<SJFPN)&&(Process[i].ArrivalTime==Process[j].ArrivalTime))    //判断是否有两个进程同时到达{if(Process[j].SJF_ALLTIME<Process[i].SJF_ALLTIME){run_time=Process[i].SJF_ALLTIME;i=j;}j++;}//查找下一个被调度的进程//对找到的下一个被调度的进程求相应的参数PID_ORDERED=i;Process[PID_ORDERED].ServiceTime=Process[PID_ORDERED].ArrivalTime;Process[PID_ORDERED].FinishTime=Process[PID_ORDERED].ServiceTime+Process[PID_ORDERED].SJF_ALLTIME;Process[PID_ORDERED].STATE=1;temp_time=Process[PID_ORDERED].FinishTime;Process[PID_ORDERED].order=1;PRESENT_PNUMBER=1;while(PRESENT_PNUMBER<SJFPN){for(j=0;j<SJFPN;j++){if((Process[j].ArrivalTime<=temp_time)&&(!Process[j].STATE)){run_time=Process[j].SJF_ALLTIME;PID_ORDERED=j;break;}}for(j=0;j<SJFPN;j++){if((Process[j].ArrivalTime<=temp_time)&&(!Process[j].STATE))if(Process[j].SJF_ALLTIME<run_time){run_time=Process[j].SJF_ALLTIME;PID_ORDERED=j;}}//查找下一个被调度的进程//对找到的下一个被调度的进程求相应的参数Process[PID_ORDERED].ServiceTime=temp_time;Process[PID_ORDERED].FinishTime=Process[PID_ORDERED].ServiceTime+Process[PID_ORDERED].SJF_ALLTIME;Process[PID_ORDERED].STATE=1;temp_time=Process[PID_ORDERED].FinishTime;PRESENT_PNUMBER++;Process[PID_ORDERED].order=PRESENT_PNUMBER;}return 0;}

5 系统测试 (UTF-8编码  可在 WINDOWS &LINUX环境下运行)

5.1Linux环境下编译主程序生成a.out文件

5.2运行a.out文件  (运行时可选择PRIORITY以及ALLTIME的生成方式)

5.2.1轮转调度算法的实现演示

5.2.2静态优先级调度算法的实现演示

5.2.3动态优先级调度算法的实现演示

5.2.4最短进程优先调度算法的实现演示  (为体现各进程的作业时长选择手动输入)

6 设计小结

本次模拟,实现了进程的轮转调度、静态优先级调度、动态优先级调度、最短进程优先调度。在整个实现过程中,出现了许多问题,最值得注意的问题如下,:

  1. 代码编写过程中的问题

    1. 四种调度算法中,动态优先级调度算法较为复杂,在实现进程的优先级更新时出现了较大的困难
    2. 在对静态优先级进行模拟时,由于对ALLTIME的使用限制,造成对ALLTIME的更新操作正常,最终通过添加num计数器,解决了ALLTIME在进程执行结束后归零的问题
    3. 由于各种调度方法的要求不一,因此对PCB结构的定义也出现了一定的选择问题
  1. 代码合并中的问题

    1. 对每种调度算法采用了不同的PCB结构,因此各PCB中的属性不一
    2. 每种调度算法中对某些属性的命名产生了冲突
    3. 在对程序进行合并时,最初使用了GOTO语句,但在考虑后,将程序更改为了SWITCH分支结构
  2. 程序运行中的问题
    1. 使用了部分Linux操作系统不支持的库函数,在Linux环境下运行时出现了部分编译错误。如gets()函数的使用,最终将其更改为了cin.get()函数。
    2. 在对库函数做修改后,Linux环境下运行程序时,四种调度均可正常实现,但对SP算法的调试并未彻底完成。当在Windows环境下使用原库函数时,程序可以正常无误地运行;在虚拟机中运行时,目前还未完成:由于库函数的使用导致“未知原因造成SP算法中,对4个及以上进程调度出现无限循环”的BUG。

本次模拟,到此并没有真正结束,对于程序的调试并没有真正达到我们满意的效果,但在Windows系统上已然完善,后续会继续对Linux操作系统下因为库函数的问题导致的程序细微异常进行处理,直至完善。

操作系统课程设计进程调度模拟相关推荐

  1. 操作系统课程设计——进程调度模拟程序(JAVA语言实现)

    本科期间的一些学习回忆记录(自己用) 一.课程设计的任务和要求 本次课程设计的题目是,时间片轮转调度算法的模拟实现.要求在充分理解时间片轮转调度算法原理的基础上,编写一个可视化的算法模拟程序.  具体 ...

  2. 操作系统作业调度算法c语言,操作系统课程设计报告电梯调度算法c语言实现.doc...

    操作系统课程设计报告电梯调度算法c语言实现 操作系统课程设计报告电梯调度算法c语言实现 :调度 算法 电梯 课程设计 操作系统 操作系统课程设计报告 模拟操作系统课程设计 写一个简单的操作系统 篇一: ...

  3. 华南理工大学计算机操作系统课程设计大作业银行家死锁避免算法模拟,2016春操作系统大作业银行家死锁避免算法模拟.doc...

    文档介绍: 2016春操作系统大作业银行家死锁避免算法模拟20160501华南理工大学"计算机操作系统"课程设计大作业计算机科学与技术专业:春2015班级:号:2015047420 ...

  4. 操作系统课程设计--使用多线程模拟时间片轮转法调度

    本篇博文分享操作系统课程设计–使用多线程模拟时间片轮转法调度的思路及代码. 实验环境:虚拟机ubuntu18.04 ,VS Code 博主分享仅为互相学习之用,不懂的地方可以留言提问,谨防抄袭!!!谢 ...

  5. java编写文件系统的方法_操作系统课程设计模拟文件系统Java

    [实例简介] 一个操作系统课程设计,使用java语言模拟磁盘文件系统实现,实现了FAT算法 [实例截图] [核心代码] e692cc3b-c785-40f6-babe-2f9d5383f034 └── ...

  6. 操作系统课程设计---实验六 银行家算法的模拟与实现

    实验六 银行家算法的模拟与实现 完整课程设计源码及其报告查看:陈陈的操作系统课程设计 1.实验目的 (1) 进一步理解进程的并发执行. (2) 加强对进程死锁的理解,理解安全状态与不安全状态的概念. ...

  7. 操作系统课程设计---实验七 磁盘调度算法的模拟与实现

    实验七 磁盘调度算法的模拟与实现 完整课程设计源码及其报告查看:陈陈的操作系统课程设计 1.实验目的 (1) 了解磁盘结构以及磁盘上数据的组织方式. (2) 掌握磁盘访问时间的计算方式. (3) 掌握 ...

  8. 计算机操作系统课设总结,计算机操作系统课程设计

    <计算机操作系统课程设计>由会员分享,可在线阅读,更多相关<计算机操作系统课程设计(36页珍藏版)>请在人人文库网上搜索. 1.操作系统课程设计实验报告姓 名: 李文孝 班 级 ...

  9. python枪战项目计划书_燕山大学操作系统课程设计计划书

    燕山大学操作系统课程设计计划书 燕山大学课程设计计划书 课程设计名称:操作系统 题目:多道程序缓冲区协同操作 年级:2016级 开发小组名称:WWW. 小组负责人: 课题组成员: 姓名 学号 班级 分 ...

最新文章

  1. winform模拟登陆网页_【教程】模拟登陆网站 之 C#版(内含两种版本的完整的可运行的代码)...
  2. pip安装包以后jupyter不能导入的解决办法
  3. trigger() --工作中问题nav样式
  4. 禁用导航栏的右滑返回实现全屏手势返回
  5. android monkey优化,GitHub - baozhida/AndroidMonkey: 这个项目是CrashMonkey4Android可执行文件,修复了一些bug,做了一些优化...
  6. 【Python】Matplotlib使用Cursor实现UI定位
  7. Oracle11默认用户名和密码
  8. apexsql使用方法_使用ApexSQL审核执行SQL Server审核
  9. 英语面试功略:英语口语突击法
  10. 十进制转化成八进制(一到十六进制)
  11. MyBatis教程看这一篇就够啦,简单又全面(IDEA版)
  12. BZOJ 3786: 星系探索 ETT
  13. 【ps功能精通】3.图层和选取
  14. win10搭建网络代理,供Linux使用
  15. 系统设计-开放平台(一)
  16. 不会聊天?不会撩妹?宅男如何走出自闭的循环圈
  17. 怎样运用EDIUS中的色彩平衡滤镜较色
  18. 飞机一般是什么操作系统?
  19. html需要编译执行吗,Javascript代码需要编译以后才能执行。
  20. uboot boot ags

热门文章

  1. Python Matplotlib绘制柱状图(bar和barh函数)详解
  2. department apartment
  3. niosii spi 外部_转载:NIOS II spi详解
  4. linux系统管理及配置
  5. 〖Python零基础入门篇(60)〗 - 随机模块 - random
  6. VMware安装windows server2008R2x64
  7. yolov5训练模型
  8. 编程中等于号的不同含义
  9. 推荐28个网站,让你边玩边学
  10. 数据库的内外链接和左右链接