时间片轮转调度算法实验报告记录
- 格式:docx
- 大小:105.63 KB
- 文档页数:16
(08信管)进程时间片轮转调度算法--操作系统实验报告操作系统实验报告—进程时间片轮转调度算法一、实验题目:进程时间片轮转调度算法二、实验原理:在多道程序系统中,一个作业被提交后必须经过处理机调度后,方能获得处理机执行。
对调度的处理又都可采用不同的调度方式和调度算法。
调度算法是指:根据系统的资源分配策略所规定的资源分配算法。
三、实验目的:1、加深对进程概念的理解,明确进程和程序的区别。
2、深入系统如何组织进程、创建进程。
3、进一步认识如何实现处理器调度。
4、通过对进程调度算法的设计,深入理解进程调度的原理。
5、加深对时间片轮转调度算法的理解。
四、实验要求:用C++语言编写程序完成单处理机的进程调度,要求采用时间片轮转调度算法。
实验具体要求包括:首先确定作业控制块的内容和组成方式;然后完成作业调度;最后编写主函数,并对所做工作进行测试。
五、语言环境:计算机基本配置要求:操作系统:WIN 98/2000/XP/2003 等Windows平台内存:256MB及以上主存64KB(Memory)(以KB为单位分配)开发语言:Visual C++ 6.0五、数据结构typedef struct jcb{char name[N];int prio;int round;int cputime;int needtime;int count;char state;struct node *next;}JCB六、参考源程序#include#include#include#includetypedef struct node{char name[10];int prio;int round;int cputime;int needtime;int count;char state;struct node *next;}PCB;PCB *finish,*ready,*tail,*run; //队列指针int N; //进程数void firstin(){run=ready; //就绪队列头指针赋值给运行头指针run->state='R'; //进程状态变为运行态]ready=ready->next; //就绪队列头指针后移到下一进程}//输出标题函数void prt1(char a){if(toupper(a)=='P') //优先级法cout<<" "<<endl;< p="">cout<<"进程名占用CPU时间到完成还要的时间轮转时间片状态"<<endl;< p="">}//进程PCB输出void prt2(char a,PCB *q){if(toupper(a)=='P') //优先级法的输出cout<name<<" "<cputime<<" "<needtime<<" "<<q->round<<" "<state<<endl;< p="">}//输出函数void prt(char algo){PCB *p;prt1(algo); //输出标题if(run!=NULL) //如果运行指针不空prt2(algo,run); //输出当前正在运行的PCB p=ready; //输出就绪队列PCBwhile(p!=NULL){prt2(algo,p);p=p->next;}p=finish; //输出完成队列的PCB while(p!=NULL){prt2(algo,p);p=p->next;}getchar(); //按住任意键继续}//时间片轮转的插入算法void insert(PCB *q){PCB *p1,*s,*r;s=q; //待插入的PCB指针p1=ready; //就绪队列头指针r=p1; //*r做pl的前驱指针while(p1!=NULL)if(p1->round<=s->round) {r=p1;p1=p1->next;}if(r!=p1){r->next=s;s->next=p1;}else{s->next=p1; //否则插入在就绪队列的头ready=s;}}//优先级创建初void create(char alg){PCB *p;int i,time;char na[10];ready=NULL;finish=NULL;run=NULL;cout<<"输入进程名及其需要运行的时间:"< {p=new PCB;cin>>na;cin>>time;strcpy(p->name,na);p->cputime=0;p->needtime=time;p->state='W';p->round=0;if(ready!=NULL)insert(p);else{p->next=ready;ready=p;}cout<<"输入进程名及其需要运行的时间:"<<=""> prt(alg);run=ready;ready=ready->next;run->state='R';}void timeslicecycle(char alg){while(run!=NULL){run->cputime=run->cputime+10;run->needtime=run->needtime-10;run->round=run->round+10;if(run->needtime<=0){run->next=finish;finish=run;run->state='F';run=NULL;if(ready!=NULL)firstin();}else{run->state='W';insert(run);firstin();}prt(alg);}}//主函数void main(){char algo='P'; //算法标记cout<<"输入进程的个数:";cin>>N; //输入进程数create(algo); //创建进程timeslicecycle(algo); //优先级法调度} //main()七、运行结果1、输入数据2、运行结果示例(1)数据输入完成后的初始状态,进程标识为x1的进程首先得到调度,运行10个时间单位。
操作系统实验报告实验二时间片轮转进程调度算法学号:班级:姓名:【实验题目】: 时间片轮转进程调度算法【实验目的】通过这次实验, 加深对进程概念的理解, 进一步掌握进程状态的转变、进程调度的策略与对系统性能的评价方法。
【实验内容】问题描述:设计程序模拟进程的时间片轮转RR 调度过程。
假设有n 个进程分别在T1, … ,Tn 时刻到达系统, 它们需要的服务时间分别为S1, … ,Sn 。
分别利用不同的时间片大小q, 采用时间片轮转RR 进程调度算法进行调度, 计算每个进程的完成时间, 周转时间和带权周转时间, 并且统计n 个进程的平均周转时间和平均带权周转时间。
程序要求如下:1)进程个数n ;每个进程的到达时间T 1, … ,T n 和服务时间S 1, … ,S n ;输入时间片大小q 。
2)要求时间片轮转法RR 调度进程运行, 计算每个进程的周转时间, 带权周转时间, 并且计算所有进程的平均周转时间, 带权平均周转时间;3)输出: 要求模拟整个调度过程, 输出每个时刻的进程运行状态, 如“时刻3: 进程B开始运行”等等;4)输出:要求输出计算出来的每个进程的周转时间, 带权周转时间, 所有进程的平均周转时间, 带权平均周转时间。
实现提示:用C++语言实现提示:1)程序中进程调度时间变量描述如下:int ArrivalTime[100];int ServiceTime[100];int PServiceTime[100];int FinishTime[100];int WholeTime[100];double WeightWholeTime[100];double AverageWT,AverageWWT;bool Finished[100];➢2)进程调度的实现过程如下:➢变量初始化;➢接收用户输入n, T1, … ,Tn, S1, … ,Sn;时间片大小q;➢按照时间片轮转RR算法进行进程调度, 计算进程的完成时间、周转时间和带权周转时间;➢计算所有进程的平均周转时间和平均带权周转时间;➢按格式输出调度结果。
实验二时间片轮转算法实验报告一、实验目的本次实验的主要目的是了解时间片轮转算法的工作原理,学习如何使用时间片轮转算法进行进程调度,并了解时间片大小对进程调度的影响。
二、实验原理时间片轮转算法是一种公平的进程调度算法,它采用循环队列的形式,将所有需要运行的进程按照到达时间排序,并将它们按照轮转的方式依次执行,每个进程在一个时间片内执行一定的时间(时间片大小),然后被暂停并放在队列的末尾等待下一次调度。
当一个进程的时间片用完后,它会被暂停并放在队列的最后,而在这个时间片内没有执行完的进程会被暂停并放到队列的开头,以便继续下一轮的运行。
这样一直循环下去,直到所有进程都运行完毕。
三、实验步骤1.设定进程数量和时间片大小。
2.定义进程结构体,包括进程ID、到达时间、服务时间、剩余时间等信息。
3.初始化所有进程,并按照到达时间排序。
4.创建一个循环队列,并将所有已到达的进程入队。
5.按照时间片大小循环执行以下步骤:a.从队列中取出一个进程,执行一次时间片大小的时间。
b.更新队列中所有进程的剩余时间。
c.如果剩余时间大于0,将进程放入队尾。
d.如果剩余时间等于0,表示进程执行完毕,将其从队列中移除。
e.输出每个时间片的调度情况。
6.统计平均等待时间和平均周转时间,并输出结果。
四、实验结果本次实验我们设置了4个进程,并且时间片大小为3、以下是每个时间片的调度情况:时间片1:进程1执行,剩余时间为2时间片2:进程2执行,剩余时间为4时间片3:进程3执行,剩余时间为5时间片4:进程1执行,剩余时间为1时间片5:进程2执行,剩余时间为3时间片6:进程3执行,剩余时间为4时间片7:进程4执行,剩余时间为2时间片8:进程1执行,剩余时间为0,进程1执行完毕时间片9:进程2执行,剩余时间为2时间片10:进程3执行,剩余时间为3时间片11:进程4执行,剩余时间为1时间片12:进程2执行,剩余时间为1时间片13:进程3执行,剩余时间为2时间片14:进程4执行,剩余时间为0,进程4执行完毕时间片15:进程2执行,剩余时间为0,进程2执行完毕时间片16:进程3执行,剩余时间为1时间片17:进程3执行,剩余时间为0根据以上调度情况,我们可以计算出平均等待时间和平均周转时间。
xx大学操作系统实验报告姓名:学号:班级:实验日期:实验名称:时间片轮转RR进程调度算法实验二时间片轮转RR进程调度算法1.实验目的:通过这次实验,理解时间片轮转RR进程调度算法的运行原理,进一步掌握进程状态的转变、进程调度的策略及对系统性能的评价方法。
2.需求分析(1) 输入的形式和输入值的范围;输入:进程个数n 范围:0<n<=100时间片q依次输入(进程名进程到达时间进程服务时间)所有进程平均带权周转时间:(3) 程序所能达到的功能1)进程个数n,输入时间片大小q,每个进程的到达时间T1, … ,T n和服务时间S1, … ,S n。
2)要求时间片轮转法RR调度进程运行,计算每个进程的周转时间和带权周转时间,并且计算所有进程的平均周转时间和带权平均周转时间;3)输出:模拟整个调度过程,输出每个时刻的进程运行状态;4)输出:输出计算出来的每个进程的周转时间、带权周转时间、所有进程的平均周转时间以及带权平均周转时间。
(4) 测试数据,包括正确的输入及其输出结果和含有错误的输入及其输出结果。
正确输入:错误输入:2、概要设计所有抽象数据类型的定义:static int MaxNum=100int ArrivalTime //到达时间int ServiceTime //服务时间int FinishedTime //结束时间int WholeTime //周转时间double WeightWholeTime //带权周转时间double AverageWT //平均周转时间double AverageWWT //平均带权周转时间主程序的流程:●变量初始化●接受用户输入的n,q ,T1…..Tn,S1….Sn;●进行进程调度,计算进程的开始运行时间、结束时间、执行顺序、周转时间、带权周转时间;●计算所有进程的平均周转时间、平均带权周转时间;●按照格式输出调度结果。
各程序模块之间的层次(调用)关系Main函数通过对Input函数进行调用,对函数的成员变量进行赋值,再通过RRAlgorithm函数求出题目要求的各个数据结果,最后通过display函数对结果进行格式输出。
时间片轮转调度算法实验报告一、引言时间片轮转调度算法是一种常见的操作系统调度算法,它的主要思想是将CPU时间分成若干个时间片,每个进程在一个时间片内执行一定的时间,然后切换到下一个进程执行。
本实验通过使用C语言模拟实现时间片轮转调度算法,并对其进行评估和比较,以便更好地理解该调度算法的性能和特点。
二、实验目的1.理解时间片轮转调度算法的原理和实现方式;2.实现一个简单的时间片轮转调度算法模拟程序;3.比较时间片长度对调度算法性能的影响;4.分析时间片轮转调度算法的优缺点。
三、实验过程1.设计数据结构和算法在开始实验之前,我们首先需要设计数据结构和算法。
在本实验中,我们使用一个队列来表示就绪队列,并使用一个指针来标记当前执行的进程。
2.实现时间片轮转调度算法模拟程序根据设计的数据结构和算法,我们使用C语言编写了一个简单的时间片轮转调度算法模拟程序。
程序首先会要求用户输入进程数量和每个进程的执行时间,然后根据输入的信息,使用时间片轮转调度算法对进程进行调度并统计各个进程的等待时间和周转时间。
3.进行实验和分析我们进行了多组实验,通过改变时间片的长度,观察时间片轮转调度算法的性能。
并对实验结果进行统计和分析,比较不同时间片长度下的平均等待时间和平均周转时间。
四、实验结果和分析在本节,我们将介绍实验的结果和分析。
1.实验结果我们使用不同时间片长度进行了多组实验,得到了如下的结果:时间片长度,平均等待时间,平均周转时间------------,-------------,-------------1,5,152,3,134,2,128,1,112.结果分析通过对实验结果的分析,我们可以得出以下结论:-随着时间片长度的增加,进程的平均等待时间和平均周转时间都呈现下降的趋势。
这是因为时间片越长,每个进程执行的时间就越长,进程切换的次数就越少,从而提高了系统的效率。
-当时间片长度较小时,进程的平均等待时间和平均周转时间较长。
时间片轮转法完成进程调度【实验目的】(1)加深对进程的理解(2)理解进程控制块的结构(3)理解进程运行的并发性(4)掌握时间片轮转法进程调度算法【实验内容】(1)建立进程控制块(2)设计三个链队列.分别表示运行队列、就绪队列和完成队列(3)用户输入进程标识符以及进程所需的时间.申请空间存放进程PCB信息。
(4)每一个时间片结束输出各进程的进程号.CPU时间(即已经占用的CPU时间).所需时间(即还需要的CPU时间).以及状态(即用W表示等待.R表示运行.F表示完成)【程序代码】#include "stdio.h"#include"stdlib.h"struct PCB{int pid; //进程标识符int rr; //已运行时间int time; //进程要求运行时间char sta; //进程的状态struct PCB *next; //链接指针};struct PCB pcb1,pcb2,pcb3,pcb4,pcb5,*tail,*head,*rp;init(){int i,time;pcb1.pid = 1;pcb2.pid = 2;pcb3.pid = 3;pcb4.pid = 4;pcb5.pid = 5;pcb1.rr =pcb2.rr =pcb3.rr =pcb4.rr =pcb5.rr = 0;pcb1.sta = pcb2.sta = pcb3.sta = pcb4.sta = pcb5.sta = 'w'; printf("请输入时间片p1需要运行的时间:");scanf("%d",&time);pcb1.time = time;printf("请输入时间片p2需要运行的时间:");scanf("%d",&time);pcb2.time = time;printf("请输入时间片p3需要运行的时间:");scanf("%d",&time);pcb3.time = time;printf("请输入时间片p4需要运行的时间:");scanf("%d",&time);pcb4.time = time;printf("请输入时间片p5需要运行的时间:");scanf("%d",&time);pcb5.time = time;pcb1.next=&pcb2;pcb2.next=&pcb3;pcb3.next=&pcb4;pcb4.next=&pcb5;pcb5.next=&pcb1;head = &pcb1;tail = &pcb5;}void printf1(){printf("+---------------|---------------|---------------|---------------+\n");printf("|\tpid\t|\trr\t|\ttime\t|\tSTA\t|\n");printf("|---------------|---------------|---------------|---------------|\n");}printf2(){printf("processes p%d running\n",head->pid);printf1();printf("|\t%d\t|\t%d\t|\t%d\t|\t%c\t|\n",head->pid,head->rr,head->time,head->sta);printf("|---------------|---------------|---------------|---------------|\n");rp=head;while(rp!=tail){rp=rp->next;printf("|\t%d\t|\t%d\t|\t%d\t|\t%c\t|\n",rp->pid,rp->rr,rp->time,rp->sta);printf("|---------------|---------------|---------------|---------------|\n");}}operation(){int flag=1;while (flag<=5){head->rr ++;if ((head->rr==head->time)||(head->time==0)){tail->sta='w';head->sta='f';printf2();head=head->next;tail->next=head;flag++;}else{tail->sta='w';head->sta='r';printf2();tail=head;head=head->next;}}}void main(){init(); //初始化printf("this is the begin state :\n"); printf2(); //显示初始状态operation(); //运行}【结果截图】。
操作系统实验报告第一次实验——时间片调度轮转算法实验时间:2014.11.7院系:计算机科学与技术学院班级:软件2班实验要求:(1)实验选题:时间片调度轮转算法(2)程序流程图及程序代码程序代码:#include<stdio.h>#include<conio.h>#define N 20typedef struct pcb{char pname[N];int runtime;int arrivetime;char state;struct pcb*next;}PCB;PCB head_input;PCB head_run;PCB * pcb_input;static char R='r',C='c'; unsigned long current;void inputprocess();int readyprocess();int readydata();int runprocess();FILE *f;int readyprocess(){while(1){if(readydata()==0)return 1;elserunprocess();}}int readydata(){if(head_input.next==NULL){if(head_run.next==NULL)return 0;elsereturn 1;}PCB *p1,*p2,*p3;p1=head_run.next;p2=&head_run;while(p1!=NULL){p2=p1;p1=p2->next;}p1=p2;p3=head_input.next;p2=&head_input;while(p3!=NULL){if(((unsigned long)p3->arrivetime<=current)&&(p3->state==R)){printf("时间片为%8d(时间%4d);进程%s 开始,\n",current,(current+500)/1000,p3->pname);fprintf(f,"时间片为%8d(时间%4d);进程%s 开始,\n",current,(current+500)/1000,p3->pname);p2->next=p3->next;p3->next=p1->next;p1->next=p3;p3=p2;}p3=p3;p3=p3->next;}return 1;}int runprocess(){PCB *p1,*p2;if(head_run.next==NULL){current++;return 1;}else{p1=head_run.next;p2=&head_run;while(p1!=NULL){p1->runtime--;current++;if(p1->runtime<=0){printf("时间片为%8d 时间%4d 进程%s 结束.\n",current,(current+500)/1000,p1->pname);fprintf(f,"时间片为%8d 时间%4d 进程%s 结束.\n",current,(current+500)/1000,p1->pname);p1->state=C;p2->next=p1->next;delete p1;p1=NULL;}else{p2=p1;p1=p2->next;}}return 1;}}void inputprocess(){PCB *p1,*p2;int num;unsigned long max=0;printf("请输入进程的数量:");fprintf(f,"请输入进程的数量:");scanf("%d",&num);fprintf(f,"%d\n",&num);p1=&head_input;p2=p1;p1->next=new PCB;p1=p1->next;for(int i=0;i<num;i++){printf("请输入第%d个进程的进程名:",i+1);fprintf(f,"请输入第%d个进程的进程名:",i+1);scanf("%s",p1->pname);fprintf(f,"%s\n",p1->pname);printf("它的运行时间为:");fprintf(f,"它的运行时间为:");scanf("%d",&(p1->runtime));fprintf(f,"%d\n",&(p1->runtime));printf("它的到达时间为:");fprintf(f,"它的到达时间为:");scanf("%d",&(p1->arrivetime));fprintf(f,"%d\n",&(p1->arrivetime));p1->runtime=(p1->runtime)*1000;p1->arrivetime=(p1->arrivetime)*1000;p1->state=R;if((unsigned long)(p1->arrivetime)>max)max=p1->arrivetime;p1->next=new PCB;p2=p1;p1=p1->next;}delete p1;p1=NULL;p2->next=NULL;}void main(){f=fopen("result.txt","w");printf("时间1=1000 时间片\n");fprintf(f,"\ntime 1=1000 time slice\n");current=0;inputprocess();readyprocess();getch();fclose(f);}(3)PCB数据结构typedef struct pcb{char pname[N];int runtime;int arrivetime;char state;struct pcb*next;}PCB;(4)程序运行结果(5)总结掌握了时间片轮转调度算法,时间片的大小确定很重要。
时间片轮转进程调度实验报告实验目的通过实验,掌握时间片轮转调度算法的原理和实现方法,了解进程调度的过程,掌握进程调度的基本要素和调度过程,并能够通过编程实现时间片轮转调度算法。
实验要求1. 理解时间片轮转调度的基本原理;2. 编程实现时间片轮转进程调度算法;3. 运行程序,观察并分析进程的执行情况。
实验设备计算机一台,支持多进程操作系统。
实验原理时间片轮转调度算法是一种基于时间片的进程调度算法,主要应用于多道程序环境下。
它的基本原理是将CPU的运行时间划分为一段段的时间片,在每个时间片结束时,如果进程还未完成,就将该进程挂起,将CPU分配给下一个进程执行。
通过快速切换进程,使得每个进程都能平等地获得CPU时间。
实验过程1. 定义进程控制块(PCB)的数据结构,包括进程的ID、优先级、状态、已执行时间等;2. 定义进程队列的数据结构,使用循环队列实现,用于存储待调度的进程;3. 初始化进程队列,将待调度的进程加入队列中;4. 设置时间片大小;5. 开始执行进程调度算法:a) 从队列中取出一个进程,将其状态设置为运行状态;b) 执行该进程,计算其已执行时间;c) 如果已执行时间小于时间片大小,将进程重新加入队列;d) 如果已执行时间等于时间片大小,将进程的状态设置为挂起,并将其放回队列;6. 重复步骤5,直到队列中所有进程都执行完毕。
实验结果运行该程序,可以观察到进程按照时间片轮转调度算法依次执行,每个进程都能获得一段时间的CPU执行时间,保证了进程执行的公平性。
实验总结通过本次实验,我深入了解了时间片轮转调度算法的原理和实现方法。
时间片轮转调度算法采用了循环队列的数据结构,通过设置时间片大小来控制进程的执行时间。
该算法能够使进程获得公平的CPU时间,并且能够保证每个进程都能得到一定的执行时间。
这在多道程序环境下非常重要,可以避免某个进程长时间占用CPU资源而导致其他进程无法得到执行的情况。
掌握了时间片轮转调度算法的理论和实现方法后,我能够更好地理解进程调度的过程,并能够通过编程实现对进程的调度。
实验二时间片轮转算法一、实验目的●● 调试EOS的线程调度程序,熟悉基于优先级的抢先式调度。
●● 在了解原有EOS的基于优先级的抢先式调度策略的基础上,添加时间片轮转调度。
二、实验内容2.1 EOS的基于优先级的抢先式调度策略:EOS内核中实现的是一种基于优先级的抢先式调度策略:为线程定义了从0到31的32个优先级,其中0优先级最低,31优先级最高。
定义了一个数组: PspReadyListHeads[32],其中保存了32个链表头,每个链表都代表一个对应优先级的就绪队列。
其中下标为n的链表对应优先级为n的就绪队列。
所以,优先级为0的就绪线程要放入下标为0的链表中,优先级为8的就绪线程要放入下标为8的链表中。
EOS每隔几十毫秒就会发生中断并执行一次线程调度,在调度过程中,总是率先选择高优先级就绪队列中的线程获得处理器,而对于同一个优先级就绪队列中的多个线程,则按照先来先服务(FCFS)的顺序进行调度。
即:假如出现了比正在执行的线程优先级更高的线程处于“就绪”状态,则将CPU分配给这个高优先级的线程,而低优先级的线程就进入“就绪”状态;而假如所有“就绪”状态的线程都是同一个优先级,那么只有排在首位的线程被执行,其余同优先级别的线程都将一直处于“就绪”状态。
观察EOS内核中基于优先级的抢先式调度策略的具体实施方法:(1)新建一个EOS Kernel项目,起名为EOS_RR_XXXXXXX,(XXXXX代表学号)。
(2)按F5启动调试,在控制台中输入命令“rr”后回车,并观察结果。
(3)控制台的输出结果应该如下图所示:即,只有第0个新建的线程在第0行显示其计数在增加,说明只有第0个新建的线程在运行,其它线程都没有运行。
造成上述现象的原因是:观察ke/sysproc.c中的第690行ConsoleCmdRoundRobin函数,在该函数中调用了第649行的ThreadFunction函数创建了20个优先级别都为8的线程,而此时EOS只实现了基于优先级的抢先式调度,所以至始至终都只有第0个线程在运行。
实验报告2013——2014学年第一学期实验课程操作系统学生姓名李玉琴学院理学院实验项目基于优先数的时间片轮转调度算法调度处理器实验性质班级学号110111120实验地点二教618同组人数 1 第组实验日期第 11 周星期 2 第成绩11,12 节环境参数一、实验目的在采用多道程序设计的系统中,同时处于就绪态的进程往往有多个,当就绪态的进程数大于处理器的个数时,就需按照某种策略进行分配处理器。
本次设计模拟在单处理器情况下采用基于优先数的时间片轮转调度算法进行处理器调度,加深了解处理器调度工作过程。
二、实验内容及要求1、设计一个程序实现基于优先数的时间片轮转调度算法调度处理器。
2、假定系统有5个进程,每个进程用一个进程控制块PCB开代表,进程控制块的结构如下图1.2所示:进程名指针到达时间要求运行时间已运行时间优先数进程状态图1其中:进程名:作为进程的标识。
指针:进程按顺序排成循环链表,用指针指出下一个进程的进程控制块首地址,最后一个进程中的指针指出第一个进程的进程控制块首地址。
要求运行时间:假设进程需要运行的单位时间数。
已运行时间:假设进程已经运行的单位时间数,初值为0。
状态:可假设有两种状态,就绪状态和结束状态。
进程的初始状态都为就绪状态。
3、每次运行所设计的处理器调度程序调度进程之前,为每个进程任意确定它的要求运行时间。
4、此程序是模拟处理器调度,因此,被选中的进程并不实际启动运行,而是执行已运行时间+1来模拟进程的一次运行,表示进程已经运行过一个单位时间。
.5、在所设计的程序中应有显示或打印语句,能显示或打印每次被选中的进程名以及运行一次后进程队列的变化。
6、为进程任意确定要求运行时间,运行所设计的处理器调度程序,显示或打印逐次被选中进程的进程名以及进程控制块的动态变化过程。
7、设有一个就绪队列,就绪进程按优先数(优先数范围0-100)由小到大排列(优先数越小,级别越高)。
当某一进程运行完一个时间片后,其优先级应下调(如优先数加2或3)。
实验报告:时间片轮转RR进程调度算法题目:时间片轮转算法的实现班级:软件工程2班姓名:代其全学号:1025111022 完成日期:2012/10/23一.需求分析程序要实现时间片轮转进程调度算法(1)接收用户输入的进程数(n),,各个进程的进程名,到达时间(T1…Tn)和服务时间(S1….Sn),以及时间片大小q。
(2)输出各个进程首次运行的时间(3)输出各个进程的完成时间,周转时间,带权周转时间,所有进程的平均周转时间,以及带权平均周转时间。
(4)测试数据为: 进程数n为5, 各进程的名字,到达时间,服务时间分别为:a 0 4 ; b 1 3; c 2 5; d 3 2; e 4 4。
时间片大小q为1 和5。
二.概要设计抽象数据类型的定义:int ArrivalTime[100];//到达时间int ServiceTime[100];//服务时间int FinishTime[100];//完成时间int WholeTime[100];//周转时间double WeightWholeTime[100];//带权周转时间double AverageWT,AverageWWT;bool Finished[100];//完成标识typedef struct QNode{char name; //进程标识int arrivaltime;//到达时间int servicetime;//服务时间int workedtime; //进程已经运行的时间bool status; //表示进程的状态,1表示已经结束,0表示还未执行struct QNode *next;}QNode, *QueuePtr;typedef struct{QueuePtr front;//队头指针QueuePtr rear;//队尾指针}LinkQueue;主程序的流程:调用Init()函数初始化到达时间,服务时间,时间片等进程信息,调度RR()函数实现轮转调度发,最后调度print()函数输出运算结果三.详细设计1.初始化函数void init(){int cputime;int x,y;char name;cout<<"请输入进程的个数:";cin>>n; //进程个数cout<<endl;for(int i=0;i<n;i++){QNode node;cout<<"请输入第"<<i+1<<"个进程的名字、到达时间和服务时间:";cin>>name>>x>>y;=name;node.arrivaltime=ArrivalTime[i]=x;node.servicetime=ServiceTime[i]=y;node.workedtime=0;node.status=Finished[i]=0;node.next=NULL;array[i]=node;//cout<<"队中增加一个元素"<<endl;cout<<endl;}//各个进程的到达时间和服务时间cout<<"请输入时间片大小:";cin>>cputime;q=cputime;//时间片大小}2.RR()函数void RR(){int temp;QNode e;int count1=0;//按到达时间先后排序进程信息数组for(int i=0;i<n;i++){for(int j=1;j<n-i;j++){if(array[i].arrivaltime>array[i+1].arrivaltime){temp=array[i].arrivaltime;array[i].arrivaltime=array[i+1].arrivaltime;array[i].arrivaltime=temp;}}}//此时,array数组中的元素都是按到达时间从小到大排列的for(i=0;i<n;i++){if(Finished[i]==0){count1++;}}for(int j=0;j<n;j++)if(array[j].arrivaltime==currentTime)EnQueue(queue,array[j]);//将到达时间为当前时间的进程加入到队列中if(count1!=0)//依然有进程未完成{for(int j=0;j<n;j++){if(q>=(*queue.front->next).servicetime)//时间片大于进程服务时间时,进程一次性执行完,进入下一进程{//cout<<"";cout<<"时刻"<<currentTime<<":进程"<<queue.front->next->name<<"开始执行"<<endl;for(int x=0;x<(*queue.front->next).servicetime;x++){currentTime++;for(int y=0;y<n;y++)if(array[y].arrivaltime==currentTime)EnQueue(queue,array[y]);//将到达时间为当前时间的进程加入到队列中}(*queue.front).status=1;//将此进程状态标注为已执行// currentTime=currentTime+(*queue.front->next).servicetime;//更新当前时间cout<<"当前时间为:"<<currentTime<<endl;DeQueue(queue,e);//将此进程出队count++;Finished[count]=1;FinishTime[count]=currentTime;//当前时间为完成时间,返回存放入FinishTime[]数组中}else//时间片小于服务时间时{if((*queue.front->next).workedtime<(*queue.front->next).servicetime)//进程已工作时间小于服务时间时{if((*queue.front->next).workedtime==0)//进程已工作时间为零时{// cout<<"";cout<<"时刻"<<currentTime<<":进程"<<(*queue.front->next).name<<"开始执行"<<endl;// currentTime=currentTime+q;//更新当前时间for(int x=0;x<q;x++){currentTime++;for(int j=0;j<n;j++)if(array[j].arrivaltime==currentTime)EnQueue(queue,array[j]);//将到达时间为当前时间的进程加入到队列中}(*queue.front->next).workedtime+=q;//更新进程已工作时间DeQueue(queue,e);//将该进程出队EnQueue(queue,e);//将该进程入队,加入到了队列的末尾}else//进程工作时间不为零且未达到服务时间时{for(inti=0;i<q&&(*queue.front->next).workedtime!=(*queue.front->next).servicetime;i+ +){currentTime++;//当前时间加一for(int j=0;j<n;j++)if(array[j].arrivaltime==currentTime)EnQueue(queue,array[j]);//将到达时间为当前时间的进程加入到队列中if((*queue.front->next).workedtime==(*queue.front->next).servicetime)//已工作时间达到要求的服务时间{(*queue.front->next).status=1;count++;Finished[count]=1;DeQueue(queue,e);FinishTime[count]=currentTime;//当前时间为完成时间,返回存放入FinishTime[]数组中}}}}}}}}3.输出函数void print(int n){cout<<"完成时间:";for(int i=0;i<n;i++)cout<<FinishTime[i]<<" ";cout<<endl;cout<<"周转时间:"<<" ";for(i=0;i<n;i++){WholeTime[i]=FinishTime[i]-ArrivalTime[i];cout<<WholeTime[i]<<" ";}cout<<endl;cout<<"带权周转时间:";for(i=0;i<n;i++){WeightWholeTime[i]=double(WholeTime[i])/ServiceTime[i];cout<<WeightWholeTime[i]<<" ";}cout<<endl;for(i=1;i<n;i++){WholeTime[0]+=WholeTime[i];}AverageWT=double(WholeTime[0])/n;cout<<"平均周转时间"<<AverageWT<<endl;for(i=1;i<n;i++){WeightWholeTime[0]+=WeightWholeTime[i];}AverageWWT=WeightWholeTime[0]/n;cout<<"带权平均周转时间:"<<AverageWWT<<endl; }4.队列里封装的函数int InitQueue(LinkQueue &q){q.front=q.rear=(QueuePtr)malloc(sizeof(QNode));if(!q.front)return 0;q.front->next=NULL;return 1;}int EnQueue(LinkQueue &q,QNode &e){QueuePtr p=(QueuePtr)malloc(sizeof(QNode));if(!p)return 0;p->name=;p->arrivaltime=e.arrivaltime;p->servicetime=e.servicetime;p->status=e.status;p->workedtime=e.workedtime;p->next=NULL;q.rear->next=p;q.rear=p;return 1;}int DeQueue(LinkQueue &q,QNode &e){if(q.rear==q.front)return 0;QueuePtr p=q.front->next;=p->name;e.arrivaltime=p->arrivaltime;e.servicetime=p->servicetime;e.status=p->status;e.workedtime=p->workedtime;q.front->next=p->next;if(q.rear==p)q.rear=q.front;free(p);return 1;}四.调试分析在时间片大于所有进程的服务时间时,程序正常运行,当时间片小于某些进程的服务时间时,程序不能输出正确的运算结果。
操作系统实验报告时间片轮转调度算法“网络协议分析”实验4实验名称:用Ethereal研究DNS和HTTP协议实验目的:通过对捕获分组的分析和研究,加深对DNS协议和HTTP协议的工作原理和实现过程的理解。
实验环境:连网PC机,Ethereal网络协议分析软件实验步骤:1.安装Ethereal网络协议分析器。
2.打开Ethereal软件菜单中的Help->Contents,可学习Ethereal的使用方法。
3.开始捕获分组之前,清空客户端Web浏览器的高速缓存和DNS的高速缓存(命令为:ipconfig /flushdns)。
(想一想,为什么?)4.在Capture->Option里选择网卡类型;取消捕获分组的“混杂模式”;设置捕获过滤器为:“host 本机IP”,这样Ethereal就会只捕获从本机发出的和发往本机的分组。
5.点击Start启动协议分析器,用Ethereal捕获从本机发出和发往本机的分组。
6.在Web浏览器中输入URL(如.cn, 等,网页较简单)。
网页显示出来后,过一会儿停止捕获。
将跟踪文件保存在一个文件中。
实验结果分析:1.在跟踪列表框中找出请求网页时发出的DNS查询报文和回答报文,找出发起TCP连接的三次握手报文,找出HTTP请求报文和响应报文。
2.在协议框中找出各层协议,观察各层协议,并对照教材中DNS查询/回答报文结构和HTTP请求/响应报文结构对这些应用层报文进行分析,找出报文中各字段相应的内容,解释其含义和用途。
3.你的主机所用的DNS服务器的IP地址是多少?你的浏览器与DNS服务器之间使用传输层的什么协议进行通信?202.196.0.1DNS请求报文和应答报文的ID号一样吗?是什么?一样,0xc4a6你所请求网站的规范名是什么?mail.DNS服务器对你的域名解析请求在应答中给出了几个可用的IP地址?都是什么?2个,202.196.0.16,202.196.0.17和DNS服务器通信时,你的客户机使用的端口号是多少?DNS服务器使用的端口号是多少?64384,53你所请求Web服务器的IP地址是什么?其域名有几个层次(参看教材127页)?202.196.0.16 4个如果请求一个存在/不存在的网页,Web服务器分别会应答什么? ??等等。
实验一时间片轮转进程调度算法时间片轮转是一种常用的进程调度算法,它的基本思想是将CPU的使用时间分成若干个时间片,每个进程在一个时间片内运行一段时间。
当一个时间片用完后,就将当前进程放入就绪队列的末尾,然后选择就绪队列中的下一个进程来执行。
下面是一个简单的时间片轮转算法的实验:1. 首先,定义一个进程结构体,包括进程ID、执行时间、剩余时间等属性。
```c++struct Process {int id; // 进程IDint executionTime; // 执行时间int remainingTime; // 剩余时间Process(int id, int executionTime) {this->id = id;this->executionTime = executionTime;this->remainingTime = executionTime;}};```2. 定义一个就绪队列,用于存放所有待执行的进程。
```c++queue<Process> readyQueue;```3. 定义一个时间片大小,例如设为1。
```c++int timeSlice = 1;```4. 创建一些进程,并将它们加入就绪队列。
```c++Process p1(1, 5);Process p2(2, 3);Process p3(3, 2);Process p4(4, 4);readyQueue.push(p1);readyQueue.push(p2);readyQueue.push(p3);readyQueue.push(p4);```5. 开始执行进程调度。
```c++while (!readyQueue.empty()) {Process currentProcess = readyQueue.front(); // 获取当前要执行的进程readyQueue.pop(); // 从就绪队列中移除当前进程// 执行当前进程,更新剩余时间if (currentProcess.remainingTime > timeSlice) {currentProcess.remainingTime -= timeSlice;readyQueue.push(currentProcess); // 将剩余时间不为0的进程重新放入就绪队列} else {currentProcess.remainingTime = 0;cout << "进程" << currentProcess.id << "执行完毕。
1.实验内容(时间片轮转和优先级调度算法)(1)用C/C++/JA V A等语言来实现对N个进程采用优先权调度和时间片轮转调度。
(2)每个用来标识进程的进程控制块PCB用结构来描述,可能需要包括以下字段:⏹进程标识数ID。
⏹进程优先数PRIORITY,并规定优先数越小的进程,其优先权越高。
⏹进程已占用的CPU时间CPUTIME。
(初始都为0)⏹进程总的需要运行的时间ALLTIME。
⏹进程剩余运行时间remainTime, 当进程运行完毕时,remainTime变为0。
⏹进程的结束时间finishTime, 当进程结束时,“系统”的时间,计算周转时间用⏹进程状态STATE。
(就绪,运行,结束,根据需要决定是否使用)(3)输出:为观察进程调度是否正确,应输出进程的“执行”过程。
但是注意,我们是模拟进程执行,所以进程并不会真正“执行”,只是输出进程执行的先后顺序,和进程执行,结束的时间点。
对于时间片轮转,应该每个时间片输出一次----------------------------------------------------------Id pri cpuTime allTime0 4 3 41 32 60 4 3 4对于优先权调度,每次调度输出一次,进行的结束时间,依次输出调度进程的信息最后输出进程的周转时间,带权周转时间和系统平均周转时间等(4)实验数据:作业执行时间优先数----------------------1 10 32 6 13 2 44 4 55 8 2如果使用时间片调度算法,请自行设定时间片(如1,2等),并比较不同时间片下的周转时间等(5)实验设计:实验的小数据量使用数组或链表都可以,但考虑到真实的应用经常要删除和添加PCB,应该使用链表,如果涉及动态的插入删除,并且需要随时找最大/最小,也可以考虑用树/堆等其他数据结构(如C++中的优先级队列)。
(6)提高要求:给每个进程增加“到达”时间,重新计算优先级调度的各个结果,并验证结果是否正确2.实验目的通过模拟进程调度算法加深对进程调度的理解3.实验原理(1)周转时间:●概念:作业提交到操作系统开始到作业完成的时间包括四个部分:1、从外存中后备队列等待作业调度(高级调度)的时间2、进程在就绪队列等待进程调度(低级调度)的时间3、进程在cpu执行的时间4、进程等待IO操作完成的时间●计算:1、周转时间= 作业完成时间- 作业提交时间2、平均周转时间= 各作业周转时间之和/ 作业数3、带权周转时间= 作业周转时间/ 作业实际运行时间4、平均带权周转时间= 各作业带权周转时间之和/ 作业数(2)等待时间:1、进程/作业处于等待处理机状态时间之和2、对于进程:进程建立后等待被服务的时间之和3、对于作业:除了进程建立后的等待还包括作业在外存后备队列中等待的时间4、相应时间:用户提交请求到首次产生相应所用的时间(3)时间片轮转:●思想:公平、轮流为每个进程服务、每个进程在一定时间内得到相应●规则:按照到达就绪队列的顺序,轮流让各个进程执行一个时间片。
******************************************** 测试数据2:2 3 11 2 35 4 2测试数据3:【结论】(结果)测试数据1的运行结果(截图):测试数据2的运行结果:测试数据3的运行结果:源程序代码:#include"stdio.h"#include"stdlib.h" struct stud{错误分析:链表初始化排序过程中:指针p=Null时,不能执行q->arrive等命令;错误解决方法:将while(q->arrive<p->arrive &&q){t=q;q=q->next;}改为:while(q&&q->arrive<p->arrive){t=q;q=q->next;}2、进程运行时间大于时间片时,程序进入死循环:当进程所需时间等于时间片时,运行结果正确:进程运行时间大于时间片时,程序进入死循环:错误分析:进程所需剩余时间计算错误;错误修改:即进入死循环。
当进程所需时间小于时间片时,应立即跳出进程就绪对列。
错误修改:在output()子函数中p->rest=p->rest-slice;后面加上一个语句:if(p->rest<0)p->rest=0;实验运行结果为:实验的体会及收获:通过这次试验,我对处理机的调度算法---基于时间片轮转调度算法思想有了更深的理解;另外使我对链表的知识有了更深的理解,而且锻炼了我的思维能力,使我能更全面地思考问题,以后还需要多做些这方面的练习。
实验还需改进之处:为考虑进程所需时间小于时间片大小的情况,如:进程运行完一次时间片时间中断后,但下一个进程的提交时间要迟很多,这时候就会浪费很多时间等待,这是该程序还需改进的地方。
另外,本实验中的RR算法的时间片大小固定,所以实际是属于基本轮转法,还有种是时间片长短是变化的,即改进轮转法。
实验二时间片轮转一、实验目的弄明白时间片轮转的工作流程和原理,通过实验让自己更明白切身体会的深!时间片轮转主要是解决处理机调度进程时的优化!正确理解提高处理机的利用率及改善系统性能在很大程度上取决于处理机调度性能的好坏,在操作系统中调度的实质是一种资源分配,调度算法是指根据系统的资源分配策略规定的资源分配算法,对不同的系统和系统目标,应采用不的调度算法。
在多道程序或多任务系统中,系统同时处于就绪状态的进程有若干个。
也就是说能运行的进程数远远大于处理机个数。
为了使系统中的各进程能有条不紊地运行,必须选择某种调度策略,以选择一进程占用处理机。
通过本实验,加深对处理机调度的理解。
弄明白时间片轮转的工作流程和原理,通过实验让自己更明白切身体会的深!二、实验内容及要求试验内容就是按照时间片工作原理:时间片轮转的原则是系统将所有的就绪进程按照先来先服务的原则排成一个队列,每次调度时,把CPU分配对手进程,并令其执行一个时间片,当执行完时,有一个计时器发出时钟中断请求,该进程停止,并被送到就绪队列的末尾,然后再把处理机分配就绪队列的队列进程,同时也让它执行一个时间片!要求:1:在开始页面用户可输入进程名,给出时间片的大小和每个进程的服务时间。
2:每运行一次,给进程的服务时间减去一个时间片大小排到队尾,显示一个时间片后的新队列。
3:直到所有的进程都服务完。
三、实验感想本实验的难点是每执行一个时间片就让它排到队尾,也即重新排序,并从头开始调度执行!时间片的工作流程是:时间片轮转的原则是系统将所有的就绪进程按照先来先服务的原则排成一个队列,每次调度时,把CPU分配对手进程,并令其执行一个时间片,当执行完时,有一个计时器发出时钟中断请求,该进程停止,并被送到就绪队列的末尾,然后再把处理机分配就绪队列的队列进程,同时也让它执行一个时间片!通过亲手实验,对上述写的时间片的工作流程和原理有了更贴切的认识!本次实验遇到了很大的麻烦,及时大部分代码是借鉴网上的,但自己通过修改,来获取自己想要的,在自己的努力和同学的帮助下终于调试正确!很是高兴!。
实验一时间片轮转进程调度算法时间片轮转(Round Robin)是一种常见的进程调度算法,其核心思想是每个进程被分配一个时间片,当时间片用完时,CPU会切换到下一个进程。
这种算法简单高效,能够保证每个进程都能获得公平的CPU时间。
在时间片轮转算法中,每个进程被分配一个相同大小的时间片,通常为几十毫秒到几百毫秒不等。
当一个进程占用完了其时间片,CPU会将其放入就绪队列的末尾,并将CPU分配给队列中的下一个进程。
这种方式可以确保每个进程都有机会运行,并且不会出现某个进程长时间占用CPU,导致其他进程饥饿的情况。
时间片轮转算法的优点之一是简单易实现,只需要设置一个固定的时间片大小和一个就绪队列即可。
另外,由于每个进程都有相同的时间片,因此可以较好地保证公平性,避免某个进程长时间占用CPU而导致其他进程无法运行的情况。
然而,时间片轮转算法也存在一些缺点。
首先,如果时间片设置过小,会导致频繁的进程切换,增加了系统的开销。
而如果时间片设置过大,可能会出现某些进程长时间占用CPU的情况,降低了系统的响应速度。
因此,选择合适的时间片大小对系统的性能至关重要。
另外,时间片轮转算法对I/O密集型的进程并不友好。
由于I/O操作需要等待外部设备的响应,进程可能会在I/O操作期间主动放弃CPU,这样会导致进程在等待I/O时浪费了部分时间片。
为了解决这个问题,可以考虑将I/O操作的等待时间纳入时间片,或者采用其他更适合I/O密集型进程的调度算法。
总的来说,时间片轮转算法是一种简单高效的进程调度算法,适用于大多数情况下。
在实际应用中,需要根据系统的特点和需求选择合适的时间片大小,以提高系统的性能和响应速度。
同时,针对不同类型的进程可以结合其他调度算法,以达到更好的效果。
第1篇一、实验目的本次实验旨在通过模拟操作系统中的进程调度过程,加深对进程调度算法的理解。
实验中,我们重点研究了先来先服务(FCFS)、时间片轮转(RR)和动态优先级调度(DP)三种常见的调度算法。
通过编写C语言程序模拟这些算法的运行,我们能够直观地观察到不同调度策略对进程调度效果的影响。
二、实验内容1. 数据结构设计在实验中,我们定义了进程控制块(PCB)作为进程的抽象表示。
PCB包含以下信息:- 进程编号- 到达时间- 运行时间- 优先级- 状态(就绪、运行、阻塞、完成)为了方便调度,我们使用链表来存储就绪队列,以便于按照不同的调度策略进行操作。
2. 算法实现与模拟(1)先来先服务(FCFS)调度算法FCFS算法按照进程到达就绪队列的顺序进行调度。
在模拟过程中,我们首先将所有进程按照到达时间排序,然后依次将它们从就绪队列中取出并分配CPU资源。
(2)时间片轮转(RR)调度算法RR算法将CPU时间划分为固定的时间片,并按照进程到达就绪队列的顺序轮流分配CPU资源。
当一个进程的时间片用完时,它将被放入就绪队列的末尾,等待下一次调度。
(3)动态优先级调度(DP)算法DP算法根据进程的优先级进行调度。
在模拟过程中,我们为每个进程分配一个优先级,并按照优先级从高到低的顺序进行调度。
3. 输出调度结果在模拟结束后,我们输出每个进程的调度结果,包括:- 进程编号- 到达时间- 运行时间- 等待时间- 周转时间同时,我们还计算了平均周转时间、平均等待时间和平均带权周转时间等性能指标。
三、实验结果与分析1. FCFS调度算法FCFS算法简单易实现,但可能会导致进程的响应时间较长,尤其是在存在大量短作业的情况下。
此外,FCFS算法可能导致某些进程长时间得不到调度,造成饥饿现象。
2. 时间片轮转(RR)调度算法RR算法能够有效地降低进程的响应时间,并提高系统的吞吐量。
然而,RR算法在进程数量较多时,可能会导致调度开销较大。
时间片轮转调度算法实验报告记录————————————————————————————————作者:————————————————————————————————日期:xx大学操作系统实验报告姓名:学号:班级:实验日期:实验名称:时间片轮转RR进程调度算法实验二时间片轮转RR进程调度算法1.实验目的:通过这次实验,理解时间片轮转RR进程调度算法的运行原理,进一步掌握进程状态的转变、进程调度的策略及对系统性能的评价方法。
2.需求分析(1) 输入的形式和输入值的范围;输入:进程个数n 范围:0<n<=100时间片q依次输入(进程名进程到达时间进程服务时间)(2) 输出的形式进程名到达时间服务时间完成时间周转时间带权周转时间所有进程平均周转时间:所有进程平均带权周转时间:(3) 程序所能达到的功能1)进程个数n,输入时间片大小q,每个进程的到达时间T1, … ,T n和服务时间S1, … ,S n。
2)要求时间片轮转法RR调度进程运行,计算每个进程的周转时间和带权周转时间,并且计算所有进程的平均周转时间和带权平均周转时间;3)输出:模拟整个调度过程,输出每个时刻的进程运行状态;4)输出:输出计算出来的每个进程的周转时间、带权周转时间、所有进程的平均周转时间以及带权平均周转时间。
(4) 测试数据,包括正确的输入及其输出结果和含有错误的输入及其输出结果。
正确输入:错误输入:2、概要设计所有抽象数据类型的定义:static int MaxNum=100int ArrivalTime //到达时间int ServiceTime //服务时间int FinishedTime //结束时间int WholeTime //周转时间double WeightWholeTime //带权周转时间double AverageWT //平均周转时间double AverageWWT //平均带权周转时间主程序的流程:变量初始化●接受用户输入的n,q ,T1…..Tn,S1….Sn;●进行进程调度,计算进程的开始运行时间、结束时间、执行顺序、周转时间、带权周转时间;●计算所有进程的平均周转时间、平均带权周转时间;●按照格式输出调度结果。
各程序模块之间的层次(调用)关系Main函数通过对Input函数进行调用,对函数的成员变量进行赋值,再通过RRAlgorithm函数求出题目要求的各个数据结果,最后通过display函数对结果进行格式输出。
3、详细设计实现程序模块的具体算法。
void RRAlgorithm(){char processMoment[100]; //存储每个时间片p对应的进程名称RRqueue.push(RRarray[0]);int processMomentPoint = 0;int CurrentTime=0;int tempTime; //声明此变量控制CurrentTime的累加时间,当前进程的服务时间小于时间片q的时候,起到重要作用int i=1; //指向还未处理的进程的下标int finalProcessNumber = 0; //执行RR算法后,进程的个数int processTime[50];//CurrentTime的初始化if (RRarray[0].ServiceTime>=q){CurrentTime = q;}else{CurrentTime = RRarray[0].ServiceTime;}while(!RRqueue.empty()){for (int j=i;j<n;j++) //使得满足进程的到达时间小于当前时间的进程都进入队列{if (RRarray[j].name!=NULL && CurrentTime >= RRarray[j].ArrivalTime){RRqueue.push(RRarray[j]);i++;}}if (RRqueue.front().ServiceTime<q){tempTime = RRqueue.front().ServiceTime;}else{tempTime = q;}RRqueue.front().ServiceTime -= q; //进程每执行一次,就将其服务时间-q//将队首进程的名称放入数组中processMoment[processMomentPoint] = RRqueue.front().name;processMomentPoint++;processTime[finalProcessNumber] = tempTime;finalProcessNumber++;if (RRqueue.front().ServiceTime <= 0) //把执行完的进程退出队列{//RRqueue.front().FinishedTime = CurrentTime;RRqueue.pop(); //如果进程的服务时间小于等于,即该进程已经服务完了,将其退栈}else{//将队首移到队尾RRqueue.push(RRqueue.front());RRqueue.pop();}CurrentTime += tempTime;}//进程输出处理每个时间段对应的执行的进程cout<<"各进程的执行时刻信息:"<<endl;cout<<" "<<"0时刻--> "<<setw(2)<<processTime[0]<<"时刻";processTime[finalProcessNumber]=0;int time = processTime[0];int count = 0;for (i=0;i<finalProcessNumber;i++){count = 0;cout<<setw(3)<<processMoment[i]<<setw(3)<<endl;while(RRarray[count].name!=processMoment[i] && count<n){count++;}RRarray[count].FinishedTime = time;if (i<finalProcessNumber - 1){cout<<setw(3)<<time<<"时刻"<<" --> "<<setw(2)<<time + processTime[i+1]<<"时刻"<<setw(3);time += processTime[i+1];}}cout<<endl;//周转时间、带权周转时间、平均周转时间、带权平均周转时间的计算//1. 周转时间= 完成时间- 到达时间//2. 带权周转时间= 周转时间/服务时间for ( i=0;i<n;i++){RRarray[i].WholeTime = RRarray[i].FinishedTime - RRarray[i].ArrivalTime;RRarray[i].WeightWholeTime = (double)RRarray[i].WholeTime/RRarray[i].ServiceTime;}double x=0,y=0;for (i=0;i<n;i++){x += RRarray[i].WholeTime;y += RRarray[i].WeightWholeTime;}AverageWT = x/n;AverageWWT = y/n;}4、调试分析(1)调试过程中遇到的问题以及解决方法,设计与实现的回顾讨论和分析在算法设计时,由于一开始不知道如何将位于队首的进程,在执行完后如何移至队尾进行循环,所以思考了很久,后来想到将队首进程进行重新压入队列从而解决了此问题。
(2)算法的性能分析每个进程被分配一个时间段,即该进程允许运行的时间。
如果在时间片结束时进程还在运行,则CPU将被剥夺并分配给另一个进程。
如果进程在时间片结束前阻塞或结束,则CPU当即进行切换。
调度程序所要做的就是维护一张就绪进程列表,当进程用完它的时间片后,它被移到队列的末尾。
(3)经验体会通过本次实验,深入理解了时间片轮转RR进程调度算法的思想,培养了自己的动手能力,通过实践加深了记忆。
5、用户使用说明程序的使用说明,列出每一步的操作步骤。
YN7、附录输入进程个数和按到达时间从小到大次序输入进运行队首开始 运行时进程运行时间中短进程,进程运行完输出结果 结束带注释的源程序,注释应清楚具体#include <iostream>#include <queue>#include <iomanip>#include <fstream>#define MaxNum 100using namespace std;typedef struct{char name;int ArrivalTime;int ServiceTime;int FinishedTime;int WholeTime;double WeightWholeTime;}RR;static queue<RR>RRqueue; //声明一个队列static double AverageWT =0,AverageWWT=0; static int q; //时间片static int n; //进程个数static RR RRarray[MaxNum]; //进程结构void Input(){//文件读取模式ifstream inData;inData.open("./data4.txt");//data.txt表示q = 4的RR调度算法//data2.txt表示q = 1的RR调度算法inData>>n;inData>>q;for (int i=0;i<n;i++){inData>>RRarray[i].name;}for (i=0;i<n;i++){inData>>RRarray[i].ArrivalTime;}for (i=0;i<n;i++){inData>>RRarray[i].ServiceTime;}//用户输入模式cout<<"************************************************************** **"<<endl;cout<<"请输入进程个数n :";cin>>n;cout<<"请输入时间片q :";cin>>q;cout<<"请按到达时间的顺序依次输入进程名:"<<endl;for (i=0;i<n;i++){cin>>RRarray[i].name;}cout<<"请从小到大输入进程到达时间:"<<endl;for (i=0;i<n;i++){cin>>RRarray[i].ArrivalTime;}cout<<"请按到达时间的顺序依次输入进程服务时间:"<<endl;for (i=0;i<n;i++){cin>>RRarray[i].ServiceTime;}cout<<"************************************************************** **"<<endl;//输出用户所输入的信息cout<<"The information of processes is the following:"<<endl;cout<<setw(10)<<"进程名"<<" ";cout<<setw(10)<<"到达时间"<<" ";cout<<setw(10)<<"服务时间"<<" "<<endl;for ( i=0;i<n;i++){cout<<setw(10)<<RRarray[i].name<<" ";cout<<setw(10)<<RRarray[i].ArrivalTime<<" ";cout<<setw(10)<<RRarray[i].ServiceTime<<" "<<endl;}cout<<"************************************************************** **"<<endl;}void RRAlgorithm(){char processMoment[100]; //存储每个时间片p对应的进程名称RRqueue.push(RRarray[0]);int processMomentPoint = 0;int CurrentTime=0;int tempTime; //声明此变量控制CurrentTime的累加时间,当前进程的服务时间小于时间片q的时候,起到重要作用int i=1; //指向还未处理的进程的下标int finalProcessNumber = 0; //执行RR算法后,进程的个数int processTime[50];//CurrentTime的初始化if (RRarray[0].ServiceTime>=q){CurrentTime = q;}else{CurrentTime = RRarray[0].ServiceTime;}while(!RRqueue.empty()){for (int j=i;j<n;j++) //使得满足进程的到达时间小于当前时间的进程都进入队列{if (RRarray[j].name!=NULL && CurrentTime >= RRarray[j].ArrivalTime){RRqueue.push(RRarray[j]);i++;}}if (RRqueue.front().ServiceTime<q){tempTime = RRqueue.front().ServiceTime;}else{tempTime = q;}RRqueue.front().ServiceTime -= q; //进程每执行一次,就将其服务时间-q//将队首进程的名称放入数组中processMoment[processMomentPoint] = RRqueue.front().name;processMomentPoint++;processTime[finalProcessNumber] = tempTime;finalProcessNumber++;if (RRqueue.front().ServiceTime <= 0) //把执行完的进程退出队列{//RRqueue.front().FinishedTime = CurrentTime;RRqueue.pop(); //如果进程的服务时间小于等于,即该进程已经服务完了,将其退栈}else{//将队首移到队尾RRqueue.push(RRqueue.front());RRqueue.pop();}CurrentTime += tempTime;}//进程输出处理每个时间段对应的执行的进程cout<<"各进程的执行时刻信息:"<<endl;cout<<" "<<"0时刻--> "<<setw(2)<<processTime[0]<<"时刻";processTime[finalProcessNumber]=0;int time = processTime[0];int count = 0;for (i=0;i<finalProcessNumber;i++){count = 0;cout<<setw(3)<<processMoment[i]<<setw(3)<<endl;while(RRarray[count].name!=processMoment[i] && count<n){count++;}RRarray[count].FinishedTime = time;if (i<finalProcessNumber - 1){cout<<setw(3)<<time<<"时刻"<<" --> "<<setw(2)<<time + processTime[i+1]<<"时刻"<<setw(3);time += processTime[i+1];}}cout<<endl;//周转时间、带权周转时间、平均周转时间、带权平均周转时间的计算//1. 周转时间= 完成时间- 到达时间//2. 带权周转时间= 周转时间/服务时间for ( i=0;i<n;i++){RRarray[i].WholeTime = RRarray[i].FinishedTime - RRarray[i].ArrivalTime;RRarray[i].WeightWholeTime = (double)RRarray[i].WholeTime/RRarray[i].ServiceTime;}double x=0,y=0;for (i=0;i<n;i++){x += RRarray[i].WholeTime;y += RRarray[i].WeightWholeTime;}AverageWT = x/n;AverageWWT = y/n;}void display(){cout<<"******************************************************"<<endl;cout<<"RR调度算法执行后:进程相关信息如下:"<<endl;cout<<setw(10)<<"进程名(ID)"<<" ";cout<<setw(10)<<"到达时间"<<" ";cout<<setw(10)<<"服务时间"<<" ";cout<<setw(10)<<"完成时间"<<" ";cout<<setw(10)<<"周转时间"<<" ";cout<<setw(10)<<"带权周转时间"<<endl;for (int i = 0;i<n;i++){cout<<setw(10)<<RRarray[i].name<<" ";cout<<setw(10)<<RRarray[i].ArrivalTime<<" ";cout<<setw(10)<<RRarray[i].ServiceTime<<" ";cout<<setw(10)<<RRarray[i].FinishedTime<<" ";cout<<setw(10)<<RRarray[i].WholeTime<<" ";cout<<setw(10)<<RRarray[i].WeightWholeTime<<" "<<endl;;}cout<<"所有进程的平均周转时间= "<<AverageWT<<endl;cout<<"所有进程的平均带权周转时间= "<<AverageWWT<<endl;cout<<"******************************************************"<<endl; }int main(){Input();RRAlgorithm();display();return 0;}。