短作业优先算法例题
- 格式:docx
- 大小:12.71 KB
- 文档页数:2
实验一先来先服务FCFS和短作业优先SJF进程调度算法一:需求分析程序设计的任务:设计程序模拟进程的先来先服务FCFS和短作业优先SJF调度过程。
假设有n个x进程分别在T1,… ,Tn时刻到达系统,它们需要的服务时间分别为S1,… ,Sn.分别采用先来先服务FCFS和短作业优先SJF进程调度算法进行调度,计算每个进程的完成时间、周转时间和带权周转时间,并且统计n个进程的平均周转时间和平均带权周转时间。
通过这次实验,加深对进程概念的理解,进一步掌握进程状态的转变、进程调度的策略及对系统性能的评价方法。
(1)输入的形式和输入值的范围为免去测试时候需要逐步输入数据的麻烦,输入时采用输入文件流方式将数据放在。
txt 文件中,第一行为进程个数,第二行为进程到达时间(各个进程的到达时间之间用空格隔开),第三行为进程的服务时间(每个服务时间之间用空格隔开)。
(2)输出的形式模拟整个调度过程,输出每个时刻的进程运行状态,同时输出了每个进程的完成时间,并且按要求输出了计算出来的每个进程的周转时间、带权周转时间、所有进程的平均周转时间以及带权平均周转时间。
(3)程序所能达到的功能能够模拟出进程的先来先服务FCFS算法和短作业优先SJF算法的调度过程,输入进程个数n;每个进程的到达时间T1, … ,Tn和服务时间S1, … ,Sn;选择算法1-FCFS,2-SJF,3—退出,用户做出选择即可输出对应的算法调度过程或者退出程序。
(4)测试数据,包括正确的输入及其输出结果和含有错误的输入及其输出结果测试数据及其输出结果:二:概要设计程序包括主函数、FCFS算法函数、SJF算法函数、输出函数;主函数流程:输入文件中的数据—显示各进程数据-选择算法-调用相应算法的函数-输出结果三:详细设计算法流程图:调用结束四:调试分析(1):调试过程中遇到的问题以及解决方法,设计与实现的回顾讨论和分析;开始的时候没有判断进程是否到达,导致短进程优先算法运行结果错误,后来加上了判断语句后就解决了改问题。
Shell编程题目1. 创建以下bash文件并执行找出100以内所有7的倍数。
提示:利用取余数运算%,当余数为0表示判断一个数是另一个数的整数倍。
题目2:创建以下bash文件并执行计算指定整数范围内的素数/质数的个数。
例如,#./2.sh 50 60将输出50和60之间的素数个数2。
(注:素数指,只能被1和自身整除的整数。
)Shell编程题1:#!/bin/bashx=1while [ $x –le 100 ];doa=$(expr $x % 7 )if [ $a –eq 0]; thenecho “$x”fix=$(expr $x + 1 )doneShell编程题2:#!/bin/bash#check argumentsif [ $# -lt 2 ];thenecho "argument number error!"exit 1fia=$1b=$2#one is not primeif [ $a -gt 1 ];thena2=$aelsea2=2finum=0x=$a2while [ $x -le $b]; do#check x is prime or notflag=1y=2while [ $y -lt $x ]; doc=$(expr $x % $y )if [ $c -eq 0 ]; thenflag=0fiy=$(expr $y + 1 )doneif [ $flag -eq 1 ];thenecho "$x"num=$(expr $num + 1 )fix=$(expr $x + 1 )doneecho "number of primes in [$a, $b] is $num."//按作业的到达顺序输入各作业的到达时间及需要的运行时间,按算法调度输出平均周转时间//FCFS顺序//2013.5.10#include<iostream>using namespace std;#define M 100void main(){double arrivetime[M]; //到达时间double spendtime[M]; //各自的运行时间double costtime[M]; //各自的周转时间double sum=0,ave;int N;cout<<"请输入作业个数:\n";cin>>N;cout<<"请依次输入四个作业分别到达的时间(单位:小时):\n";for(int i=0;i<N;i++){cin>>arrivetime[i];}cout<<"请依次输入四个作业分别需要运行的时间(单位:小时):\n";for(int j=0;j<N;j++){cin>>spendtime[j];}double m=arrivetime[0];int l=0;for(int k=0;k<N;k++) //求出各自的周转时间{if(arrivetime[k]<=m){m+=spendtime[l];costtime[k]=m-arrivetime[k];l++;}else{m=arrivetime[k]+spendtime[k];costtime[k]=spendtime[k];l++;}}for(int n=0;n<N;n++){sum+=costtime[n];}ave=sum/N;cout<<"平均周转时间:"<<ave<<endl;}//SJF算法#include<iostream>using namespace std;void main(){double arrivetime[20]; //到达的时间double spendtime[20]; //各作业所需要的时间double costtime[20]; //各自的周转时间int N;double ave;double sum;cout<<"请输入作业的个数:";//输入作业的个数cin>>N;cout<<"请依次输入四个作业分别到达的时间(单位:小时):\n";for(int i=0;i<N;i++){cin>>arrivetime[i];}cout<<"请依次输入四个作业分别需要运行的时间(单位:小时):\n";for(int j=0;j<N;j++){cin>>spendtime[j];}int temp,temp1;for(int k=1;k<N;k++){for(int l=k+1;l<N;l++){if(spendtime[k]>spendtime[l]){temp=spendtime[k];spendtime[k]=spendtime[l];spendtime[l]=temp;temp1=arrivetime[k];arrivetime[k]=arrivetime[l];arrivetime[l]=temp1;}}}double w=arrivetime[0];int p=0;for(int n=0;n<N;n++) //求出各自的周转时间{if(arrivetime[n]<=w){w+=spendtime[n];costtime[n]=w-arrivetime[n];p++;}else{w=arrivetime[n]+spendtime[n];costtime[n]=spendtime[n];p++;}}for(int t=0;t<N;t++){sum+=costtime[t];}ave=sum/N;cout<<"平均周转时间:"<<ave<<endl;}FIFO#include<iostream>using namespace std;#define M 100void main(){int page[M]; //存进的页面int visit[M]; //页面访问顺序char flag,f[M]; //标志是否有缺页现象int table[M][M]; //打印int p,v;int i,j,k,t;cout<<"please enter your number of pages:";cin>>p;cout<<"plase enter your number of visiting:";cin>>v;cout<<"plase enter your order of visiting:";for(i=0;i<v;i++){cin>>visit[i];}for(i=0;i<p;i++){page[i]=9;}t=0; //记录缺页次数for(i=0;i<v;i++){k=0; //判断是否缺页flag=' ';while((visit[i]!=page[k])&&(k!=p)) k++;if(k==p){flag='*'; //有缺页现象t++;}elseflag=' ';if(flag=='*'){for(j=p-1;j>0;j--)page[j]=page[j-1];page[0]=visit[i];}for(k=0;k<p;k++){table[k][i]=page[k];}f[i]=flag;}cout<<"输出结果为下表(9代表为空,*代表有缺页):\n";for(i=0;i<p;i++){ //打印for(j=0;j<v;j++){cout<<table[i][j]<<" ";}cout<<endl;}for(i=0;i<v;i++){cout<<f[i]<<" ";}cout<<endl<<"共有"<<t<<"次缺页。
在作业调度中,该算法每次从后备作业队列中挑选估计服务时间最短的一个或几个作业,将他们调入内存,分配必要的资源,创建进程并放入就绪队列。
与在进程调度中的原理类似。
假设有n项作业位于就绪队列中,这些作业的请求时间用数组requestTimes按照提交时间的先后顺序存储,对应的作业服务时间(也称持续时间)用数组durations存储。
当每个作业被完成后,接下来优先选择服务时间(持续时间)短的,如果多个服务时间一样,则优先选择请求时间最先的。
采用SJF算法,计算n项作业的平均等待时间。
所有要执行的任务的请求时间必须在上一个任务完成的时间内。
假设0<= n <= 100。
测试用例:
requestTimes = {0, 2, 4, 5};
durations = {7, 4, 1, 4};
可以理解为一定首先执行第一个任务,请求时间为0,执行了7个时间单位;
接下来在服务时间最短的中选择,显然是任务3,请求时间为4,执行1个时间单位;
再接下来发现2和4这两个任务服务时间一样短,则优先选择请求时间最先的,显然是选择任务2,执行4个时间单位
最后是任务4(并且只有任务4了),请求时间为5,执行4个时间单位
等待时间:任务1是0,任务3是3,任务2是5,任务4是7,所以平均等待时间是4。
短功课(进程)优先调度算法之杨若古兰创作1.短功课(进程)优先调度算法SJ(P)F,是指对短功课或短进程优先调度的算法.它们可以分别用于功课调度和进程调度.短功课优先(SJF)的调度算法是从后备队列当选择一个或若干个估计运转时间最短的功课,将它们调入内存运转.而短进程(SPF)调度算法则是从就绪队列当选出一个估计运转时间最短的进程,将处理机分配给它,使它立即履行并不断履行到完成,或发生某事件而被梗阻放弃处理机再从头调度.SJ(P)F调度算法能无效地降低功课(进程)的平均等待时间,提高零碎吞吐量.该算法对长功课晦气,完整未考虑功课的紧迫程度.2.流程图3.代码#include<iostream.h>#include<string.h>#include<stdlib.h>struct sjf{char name[10];float arrivetime;float servicetime;float starttime;float finishtime;float zztime;float dqzztime;};sjf a[100];void input(sjf *p,int N){ int i;printf("intput the process's name & arrivetime & servicetime:\nfor exmple: a 0 100\n");for(i=0;i<=N1;i++){printf("input the %dth process's information:\n",i+1);scanf("%s%f%f",&p[i].name,&p[i].arrivetime,&p[i].ser vicetime);}}void Print(sjf *p,float arrivetime,float servicetime,float starttime,float finishtime,float zztime,float dqzztime,int N) {int k;printf("run order:");printf("%s",p[0].name);for(k=1;k<N;k++){printf(">%s",p[k].name);}printf("\nthe process's information:\n");printf("\nname\tarrive\tservice\tstart\tfinish\tzz\tdqzz\n ");for(k=0;k<=N1;k++){ printf("%s\t%.2f\t%.2f\t%.2f\t%.2f\t%.2f\t%.2f\t\n", p[k].name,p[k].arrivetime,p[k].servicetime,p[k].starttime,p[k]. finishtime,p[k].zztime,p[k].dqzztime);}}//pai xuvoid sort(sjf *p,int N){for(int i=0;i<=N1;i++)for(int j=0;j<=i;j++)if(p[i].arrivetime<p[j].arrivetime){sjf temp;temp=p[i];p[i]=p[j];p[j]=temp;}}//yun xing jieduanvoid deal(sjf *p, float arrivetime,float servicetime,float starttime,float finishtime,float &zztime,float &dqzztime,int N){ int k;for(k=0;k<=N1;k++){if(k==0){p[k].starttime=p[k].arrivetime;p[k].finishtime=p[k].arrivetime+p[k].servicetime;}else{p[k].starttime=p[k1].finishtime;p[k].finishtime=p[k1].finishtime+p[k].servicetime;} }for(k=0;k<=N1;k++){p[k].zztime=p[k].finishtimep[k].arrivetime;p[k].dqzztime=p[k].zztime/p[k].servicetime;}}void sjff(sjf *p,int N){floatarrivetime=0,servicetime=0,starttime=0,finishtime=0,zztim e=0,dqzztime=0;sort(p,N);for(int m=0;m<N1;m++){if(m==0)p[m].finishtime=p[m].arrivetime+p[m].servicetime;elsep[m].finishtime=p[m1].finishtime+p[m].servicetime;int i=0;for(int n=m+1;n<=N1;n++){if(p[n].arrivetime<=p[m].finishtime)i++;}float min=p[m+1].servicetime;int next=m+1;//m+1=nfor(int k=m+1;k<m+i;k++){if(p[k+1].servicetime<min){min=p[k+1].servicetime;next=k+1;}}sjf temp;temp=p[m+1];p[m+1]=p[next];p[next]=temp;}deal(p,arrivetime,servicetime,starttime,finishtime,zztime,dqz ztime,N);Print(p,arrivetime,servicetime,starttime,finishtime,zztime,dq zztime,N);}int main(){ int N;printf("短功课优先调度算法\n");printf("input the process's number:\n");scanf("%d",&N);input(a,N);sjf *b=a;sjf *c=a;sjff(b,N);system("PAUSE");}4.运转结果5.心得体会课程设计结束了,在此次的课程设计中不但检验了我所进修的常识,也培养了我如何去做一件事情,又如何完成一件事情的能力.通过模拟进程的调度成绩,更加深了我对于操纵零碎理论的理解,在本人的动手操纵过程中,能够体会成功的喜悦和碰到成绩本人解决的能力,对于我来说是一次提高,让本人多多的在实践中可以加深对理论的理解,也让我明白了当前应当如何更好,更高效的进修,在当前,我会更加努力.。
短作业优先调度算法(SJF)假设有n项作业位于就绪队列中,这些作业的提交时间⽤数组requestTimes按照提交时间的先后顺序存储,对应的作业服务时间(持续时间)⽤数组durations存储。
采⽤SJF算法,计算n项作业的平均等待时间。
当存在多个相同长度的短作业时,按照提交时间的先后顺序进⾏调度。
假设0<= n <= 100。
求出所有作业的平均等待时间。
函数原型:void minWaitingTime(int requestTimes[],int durations[],int n)测试⽤例:输⼊40 2 4 57 4 1 4输出:4.01 #include <stdio.h>2 #include <stdlib.h>3 #include <string.h>45#define MAX 0x7FFFFFFF67void minWaitingTime(int requestTimes[],int durations[],int n)8 {9int i,time,j,k;10float res;11int index,arriveTime,indextemp;12int *done = (int *)malloc(sizeof(int) * n); //表⽰作业是否执⾏过,1表⽰执⾏完毕,0表⽰未执⾏13int *wait = (int *)malloc(sizeof(int) * n); //表⽰等待时间14for(i = 0; i < n; ++i){15 wait[i] = 0;16 done[i] = 0;17 }1819 time = 0; //time表⽰总作业执⾏时间20for(i = 0; i < n; i++){21if(i == 0){ //执⾏第⼀个作业22 time += durations[i];23 done[i] = 1;24for(j = 1; j < n; j++){25if(requestTimes[j] < time)26 wait[j] = time - requestTimes[j];27 }28 }29else{30 index = GetMin(durations,done,n);31//判断是否有多个最短作业,如有选择其中先到达的32 arriveTime = requestTimes[index];33for(indextemp = index + 1; indextemp < n; indextemp++){34if(done[indextemp] == 0 && durations[indextemp] == durations[index] &&35 requestTimes[indextemp] < arriveTime)36 index = indextemp;37 }3839 time += durations[index];40 done[index] = 1;41//执⾏选出的最短作业,并更新其它作业的等待时间42for(indextemp = 0; indextemp < n && i < n-1; indextemp++)43if(done[indextemp] == 0 &&requestTimes[indextemp] < time)44 wait[indextemp] = time - requestTimes[indextemp];45 }46 }4748 res = 0.0;49for(i = 0; i < n; i++)50 res += wait[i];5152 printf("%f\n",res / n);5354 }55//每次取出服务时间最短且⽰执⾏过的作业56int GetMin(int durations[],int done[],int n)57 {58int i,j,min = MAX;59for(i = 0; i < n; i++)60if(durations[i] < min && done[i] == 0){61 min = durations[i];62 j = i;63 }64return j;65 }6667int main()68 {69int requestTimes[100];70int durations[100];71int i,n;72 scanf("%d",&n);73for(i = 0; i < n; i++)74 scanf("%d",&requestTimes[i]);75for(i = 0; i < n; i++)76 scanf("%d",&durations[i]);7778 minWaitingTime(requestTimes,durations,n); 7980 system("pause");81return0;82 }。
最短作业优先(抢占和非抢占)一、流程图解析:在最开始,我们先创建若干进程,选择自动运行,则在运行完后,按顺序显示运行的结果。
同理,选择手动运行,那么就是最先选择最短的作业开始运行,其实当前进程并非一定在实际运行(改变自己的状态),只是一个虚拟的运行(虚拟最短作业优先运行算法),这时我们可以做其他的事情,在做事之前,先运行虚拟算法,依照最短作业优先去改变相关进程的状态(进程可能就没有实际运行过,被虚拟算法改变了状态(就绪、等待、终止)),在做完相关事情之后,再运行虚拟算法,确定是否要发生最短作业的优先抢占。
根据以上的运行结构,我们可以在这结构的基础上,人为地设置进程状态就是改变进程状态,这时就可以发生最短作业调度的抢占和非抢占式。
我们可以进入查看进程状态,看看运行的状况,也可以进入修改进程状态,修改相关进程状态让其发生最短作业的抢占,或者进入创建进程,创建一个新的进程,这是也有可能实现最短作业优先的抢占。
二、虚拟运行算法:从进程的结构分析,进程里面有状态,到达时间(取系统时间),结束时间(取系统时间),需要运行时间,已运行时间等,我们知道第一个最短作业运行的到达时间(开始运行的时间)就是创建的时间。
在一个进程运行终止时,要设好终止的时间、改变状态等属性,这时进行进程间信息交换,终止进程的时间交给下一个要运行的进程的到达时间,这样不断下去就可以运行到最后一个进程,当发生抢占调度时,也是以上的情况运行。
先在抢占之前,就运行虚拟算法,改变相关的进程状态,发生引起抢占的事的时候就可以利用抢占来进行进程的切换。
这样就能让CPU在有工作做时就不能空闲。
直到把所有在就绪队列的进程运行完,这是CPU可以休息了,如果在CPU休息时有进程从等待进入就绪,那么CPU就要继续开工。
当我们运行完第一批输入的进程,现在CPU在空转,我们又创建了新进程,这时新进程就在创建那一刻起开始运行了,因为新进程创建好就进入了就绪的状态。
#include<iostream>#define N 4#include <string>//时间片系列#include<stdio.h>#include<stdlib.h>#define MAX 4 //进程数量#define RR 4 //时间片大小//时间片系列using namespace std;struct time{string name;float arriveTime;float runTime;float finishTime;float totalTime;float weightTotalTime;};//时间片系列struct pro{char num;int arriveTime;int burst;int rt; //记录进程被运行的次数struct pro *next;};int TOTALTIME; //记录所有进程的总时间//时间片系列//函数声明struct pro* creatList();void insert(struct pro *head,struct pro *s);struct pro* searchByAT(struct pro *head,int AT);void del(struct pro* p);int getCount(struct pro *head,int time);struct pro* searchEnd(struct pro *head);void move(struct pro *headF,struct pro *headT,int n);struct pro* creatList() //创建链表,按照进程的到达时间排列,记录所有进程的信息{struct pro* head=(struct pro*)malloc(sizeof(struct pro));head->next=NULL;struct pro* s;int i;TOTALTIME=0;cout<<"输入进程名& 到达时间& 运行时间(example:a 0 0):"<<endl;cout<<"name "<<"arrivetime "<<"runtime"<<endl;for(i=0;i<MAX;i++){s=(struct pro*)malloc(sizeof(struct pro));cin>>s->num;cin>>s->arriveTime;cin>>s->burst;TOTALTIME+=s->burst; //计算总时间s->rt=1; //rt的初始值为1s->next=NULL;insert(head,s);}return head; //到达队列中的进程按照其到达时间的先后顺序排列}void insert(struct pro *head,struct pro *s) //插入节点{struct pro *p=searchByAT(head,s->arriveTime);s->next=p->next;p->next=s;return;}struct pro* searchByAT(struct pro *head,int AT) //查找第一个到达时间大于等于AT的节点,返回其前一个指针{struct pro *p,*q;p=head;q=head->next;while(q!=NULL&&q->arriveTime<=AT){p=q;q=q->next;}return p;}void del(struct pro* p) //删除p的下一个节点{struct pro *tmp;tmp=p->next;p->next=tmp->next;return;}int getCount(struct pro *head,int time) //察看在time之前到达但未移动到运行队列的进程数量{int count=0;struct pro *s,*t;s=head;t=s->next;while(t!=NULL&&t->arriveTime<=time){s=t;t=t->next;count++; //count记录当前时刻到达的进程数}return count;}struct pro* searchEnd(struct pro *head) //查找并返回循坏队列的尾节点的前一个节点{struct pro *p,*q;p=head;q=head->next;while(q->next!=head){p=q;q=q->next;}return p;}void move(struct pro *headF,struct pro *headT,int n) //将headF后的n个节点移动到循环队列headT中{struct pro *r,*s,*t;s=headF;t=s->next;r=t; //r记录要移动的第一个节点while(n>1){t=t->next;}s->next=t->next; //以上完成从原队列中摘除相关节点,r,t分别为第一个和最后一个节点s=searchEnd(headT);if(s!=headT)s=s->next;t->next=s->next;s->next=r;struct pro *f=s;}void run(struct pro *head){int time=0; //记录当前时间int newarrive;//新到达进程数struct pro *runhead=(struct pro*)malloc(sizeof(struct pro));runhead->next=runhead; //创建新的循环链表,存放当前就绪队列中的进程struct pro *p,*q;p=runhead;q=p->next; //q记录当前应当运行的进程while(time<=TOTALTIME){newarrive=getCount(head,time);if(newarrive>0)move(head,runhead,newarrive); //将head后的newarrive个节点移动到runhead队列中if(runhead->next==runhead) //就绪队列中没有进程time++;else if(q==runhead){p=q;q=q->next;}else{cout<<"进程名:"<<q->num<<endl;cout<<"到达时间:"<<q->arriveTime<<endl;if(q->rt==1)printf("响应时间:%d\n",time-q->arriveTime);elseprintf("第%d次运行开始时间:%d\n",q->rt,time);if(q->burst<=RR){time+=q->burst;printf("第%d次运行结束时间:%d\n",q->rt,time);printf("周转时间:%d\n",time-q->arriveTime);printf("************************************\n");struct pro *tmp=q;q=q->next;p->next=q;runhead->next=q;free(tmp);}else //q->burst>RR{time+=RR;printf("第%d次运行结束时间:%d\n",q->rt,time);printf("************************************\n");q->burst-=RR;q->rt++;struct pro *h;h=runhead->next;if(h->next!=runhead){while(h->next!=runhead)h=h->next;runhead->next=q->next;h->next=q;q->next=runhead;q=runhead->next;}else{ struct pro *n;n=q;p=q;q=q->next;}}}}}//时间片系列void InputTime(time *p){int i;//countercout<<"input name & arrive time & run time(example:a 00):"<<endl;cout<<"name "<<"arrivetime "<<"runtime"<<endl;for(i=0;i<=N-1;i++){float temp1,temp2;string name;cin>>name;p[i].name=name;cin>>temp1;p[i].arriveTime=temp1;cin>>temp2;p[i].runTime=temp2;}}void Print(time *p,float totalTimeSum,float weightTotalTimeSum){cout<<"********运行次序:"<<endl;for(int k=0;k<=N-1;k++){cout<<p[k].name<<" ";}cout<<endl;cout<<"平均周转时间:"<<totalTimeSum/N<<endl;cout<<"平均带权周转时间:"<<weightTotalTimeSum/N<<endl; }void sort(time *p){for(int i=0;i<=N-1;i++)for(int j=0;j<=i;j++)if(p[i].arriveTime<p[j].arriveTime){time temp;temp=p[i];p[i]=p[j];p[j]=temp;}}void deal(time *p,float &totalTimeSum,float&weightTotalTimeSum){int k;//counterfor(k=0;k<=N-1;k++){if(k==0)p[k].finishTime=p[k].arriveTime+p[k].runTime;elsep[k].finishTime=p[k-1].finishTime+p[k].runTime;}for(k=0;k<=N-1;k++){p[k].totalTime=p[k].finishTime-p[k].arriveTime;p[k].weightTotalTime=p[k].totalTime/p[k].runTime;totalTimeSum+=p[k].totalTime;weightTotalTimeSum+=p[k].weightTotalTime;}}void FCFS(time *p){float totalTimeSum=0,weightTotalTimeSum=0;sort(p);deal(p,totalTimeSum,weightTotalTimeSum);cout<<endl;cout<<"**********************"<<endl;cout<<"***先来先服务:"<<endl;Print(p,totalTimeSum,weightTotalTimeSum);cout<<"****************"<<endl;}void SWF(time *p){float totalTimeSum=0,weightTotalTimeSum=0;sort(p);for(int m=0;m<N-1;m++){if(m==0)p[m].finishTime=p[m].arriveTime+p[m].runTime;elsep[m].finishTime=p[m-1].finishTime+p[m].runTime;int i=0;for(int n=m+1;n<=N-1;n++){if(p[n].arriveTime<=p[m].finishTime)i++;}float min=p[m+1].runTime;int follow=m+1;for(int k=m+1;k<m+i;k++){if(p[k+1].runTime<min){min=p[k+1].runTime;follow=k+1;}}time temp;temp=p[m+1];p[m+1]=p[follow];p[follow]=temp;}deal(p,totalTimeSum,weightTotalTimeSum);cout<<endl;cout<<"**********************"<<endl;cout<<"***短作业优先:"<<endl;Print(p,totalTimeSum,weightTotalTimeSum);cout<<"**********************"<<endl;}void TRRF(time *p){float totalTimeSum=0,weightTotalTimeSum=0;sort(p);for(int m=0;m<N-1;m++){if(m==0)p[m].finishTime=p[m].arriveTime+p[m].runTime;elsep[m].finishTime=p[m-1].finishTime+p[m].runTime;int i=0;for(int n=m+1;n<=N-1;n++){if(p[n].arriveTime<=p[m].finishTime)i++;}float max=(p[m].finishTime-p[m+1].arriveTime)/p[m+1].runTime;int follow=m+1;for(int k=m+1;k<m+i;k++){if(max<=(p[m].finishTime-p[k+1].arriveTime)/p [k+1].runTime){max=(p[m].finishTime-p[k+1].arriveTime)/p[k+1].runTime;follow=k+1;}}time temp;temp=p[m+1];p[m+1]=p[follow];p[follow]=temp;}deal(p,totalTimeSum,weightTotalTimeSum);cout<<endl;cout<<"**********************"<<endl;cout<<"***最高响应比优先:"<<endl;Print(p,totalTimeSum,weightTotalTimeSum);cout<<"**********************"<<endl;}void main(){int lg;cout<<"请选择任一种算法:"<<endl;cout<<"1.FCFS(先来先服务)2.SWF(短作业优先)3.TRRF(高响应比优先) 4.RR(时间片轮转)0.退出"<<endl;cin>>lg;cout<<endl;time a[N],b[N],c[N];while (lg){if(lg==1){InputTime(a);FCFS(a);cout<<endl;}//time *b=a;time *c=a;if(lg==2){InputTime(b);SWF(b);cout<<endl;}if(lg==3){InputTime(c);TRRF(c);cout<<endl;}//时间片系列if(lg==4){cout<<endl;cout<<"********时间片模拟*******"<<endl;struct pro *head=creatList();printf("当前时间片大小为:%d\n",RR);run(head);cout<<endl;}cout<<"1.FCFS(先来先服务)2.SWF(短作业优先)3.TRRF(高响应比优先) 4.RR(时间片轮转)0.退出"<<endl;cin>>lg;cout<<endl;}cout<<"您选择了退出模拟。
第三章习题【例1】有一个内存中只能装入两道作业的批处理系统,作业调度采用短作业优先的调度算法,进程调度采用以优先数为基础的抢占式调度算法。
有如表所示的作业序列,表中所列的优先数是指进程调度的优先数,且优先数越小优先级越高。
(1)列出所有作业进入内存的时刻以及结束的时刻。
(2)计算作业的平均周转时间。
作业名到达时间估计运行时间(分) 优先数A 10:00 40 5B 10:20 30 3C 10:30 50 4D 10:50 20 6答:根据题意,作业的调度和运行情况如图所示,从图中可以看出(1)A、B、C、D各作业进入内存的时刻分别是10:00、10:20、11:10、10:50;它们完成的时刻分别是11:10、10:50、12:00、12:20。
(2)A、B、C、D的周转时间分别是70分钟、30分钟、90分钟、90分钟,故它们的平均周转时间为70分钟。
【例2】对下面的5个非周期性实时任务,按最早开始截止时间优先调度算法应如何进行CPU调度?进程到达时间执行时间开始截止时间A 10 20 110B 20 20 20C 40 20 50D 50 20 90E 60 20 70答:对上面5个非周期性实时任务,按最早开始截止时间优先调度算法进程CPU调度的结果如图所示,可见采用非抢占调度方式时,系统没能保证B任务对截止时间的要求。
【例3】若有3个周期性任务,任务A要求每20ms执行一次,执行时间为10ms;任务B要求每50ms执行一次,执行时间为10ms;任务C要求每50ms 执行一次,执行时间为15ms,应如何按最低松弛度优先算法对它们进行CPU调度?答:对上面的3个周期性任务,利用最低松弛度优先算法进行调度的情况如图所示。
【例4】假定某计算机系统有R1设备3台,R2设备4台,它们被P1、P2、P3和P4这四个进程互斥共享,且已知这4个进程均以下面所示的顺序使用现有设备:→申请R1→申请R2→申请R1→释放R1→释放R2→释放R1→,请问系统允许过程中是否可能产生死锁?如果有可能的话,请举出一种情况,并画出表示死锁状态的进程-资源图。
中国地质大学(北京)操作系统原理实习报告实习题目:1、2、实习人员:学号姓名(组长)学号姓名一、题目分析在批处理系统中,短作业优先算法是一种比较好的算法,其主要的不足之处是长作业的运行得不到保证。
于是我们想到了一种办法解决这个问题,就是引用动态优先权、并使作业的优先级随着等待时间的增加而以速率a提高,长作业在等待一定的时间后,必然有机会分配到处理机,这样长作业也得到了运行。
设计并实现一个采用高响应比算法的进程调度演示程序,响应比R 定义如下:RWT/T1W/T 其中T 为该作业估计需要的执行时间,为作业在后备状态队列中的等待时W间。
每当要进行作业调度时,系统计算每个作业的响应比,选择其中R最大者投入执行。
这样,即使是长作业,随着它等待时间的增加,W/T 也就随着增加,也就有机会获得调度执行。
这种算法是介于FCFS 和SJF 之间的一种折中算法。
由于长作业也有机会投入运行,在同一时间内处理的作业数显然要少于SJF 法,从而采用HRRN 方式时其吞吐量将小于采用SJF 法时的吞吐量。
另外,由于每次调度前要计算响应比,系统开销也要相应增加。
二、数据结构结构体数组path[k]实现对进程响应比的计算Path[max] 实现对进程响应比的排序Path[ii] 实现程序的各阶段运行状况的输出三、算法流程图程序设计流程图高响应比函数执行过程流程图四、重难点分析计算每一个进程的动态优先权,需要在每执行一个进程之后计算一遍未执行进程的优先权,从中选出优先权最高的一个执行。
五、运行测试(截图)六、分工编码:实验报告:七、总结本次演算实验主要对最高响应比算法的理解和对进程调度的功能以及进程调度算法有了深入的理解。
在这次的课程设计中,计算每一个进程的动态优先权,需要在每执行一个进程之后计算一遍未执行进程的优先权,从中选出优先权最高的一个执行,因为疏忽导致了响应比的计算错误,从而加大了完成代码的时间量。
对于这次出现的这个问题,使我有了对程序设计的严谨性,课本基础知识的理解程度上有了更深刻的认识,也让我明白到了基础知识的重要性。
调度算法之最短作业优先算法最短作业优先算法⼜叫做短进程优先算法写此博⽂⽬的:1.⽅便⾃⼰复习2.给正在学习此算法的⼈⼀点参考单道(⼀次只能运⾏⼀个进程)分析:先将进程按照到达时间升序排序,第⼀个进程到达的时候不等待,直接运⾏,因为他是第⼀个到达的进程,在他之前没有进程在运⾏,当有进程到达但是有其他进程在运⾏的时候,到达的进程处于等待状态,当某个正在运⾏的进程运⾏完毕的时候,需要选择下⼀个进程,依据是:处于等待状态的进程,且运⾏时间最短(当有多个进程处于等待状态的时候,选择运⾏时间最短的进程,这个结束最短作业优先算法的核⼼)代码如下:#include<bits/stdc++.h>using namespace std;#define TAKEIN "takein"//对应的进程状态#define WAIT "wait"#define RUN "run"#define FINISH "finish"#define PNUMBER 5//进程个数typedef struct pcb{char processName[20];//进程名称int arriveTime;//进程到达时间int startTime;//进程开始时间int endTime;//进程结束时间int runTime;//进程运⾏时间⼤⼩int turnOverTime;//周转时间int userweightTurnOverTime;//带权周转时间char provessStatus[10];//进程状态} pcb;pcb pcbs[PNUMBER];//进程数组int currentTime=0;//时间int processIndex=0;//进程的编号void createPcbs()//进程初始化函数{freopen("input.txt","r",stdin);//以只读操作读⽂件printf("进程名\t到达时间\t运⾏时间\n");for(int index=0; index<PNUMBER; index++)//遍历所有进程,给进程赋初值{scanf("%s",pcbs[index].processName);scanf("%d",&pcbs[index].arriveTime);scanf("%d",&pcbs[index].runTime);pcbs[index].endTime=0;pcbs[index].startTime=0;pcbs[index].turnOverTime=0;pcbs[index].userweightTurnOverTime=0;strcpy( pcbs[index].provessStatus,TAKEIN);printf("%s \t%d \t%d\n", pcbs[index].processName, pcbs[index].arriveTime, pcbs[index].runTime);}printf("\n***********************************************\n");}void printfPcbsInfo()//打印所有进程的所有信息{printf("当前时间为:%d时各进程的信息.....\n\n",currentTime);printf("进程名\t到达时间\t运⾏时间\t开始时间\t结束时间\t周转时间\t带权周转时间\t状态\n");for(int index=0; index<PNUMBER; index++){printf("%s\t%8d\t%8d\t%8d\t%8d\t%8d\t%8d\t%4s\n",pcbs[index].processName,pcbs[index].arriveTime,pcbs[index].runTime,pcbs[index].startTime,pcbs[index].endTime,pcbs[index].turnOverTime,pcbs[index].userweightTurnOverTime,pcbs[index].provessStatus); }}void sortPcbs()//按到达时间的升序排序{int minIndex=0,minValue=0;for(int i=0; i<PNUMBER; i++){minIndex=i;minValue=pcbs[i].arriveTime;for(int j=i; j<PNUMBER; j++){if(pcbs[j].arriveTime<minValue){minValue=pcbs[j].arriveTime;//保存最⼩的minIndex=j;}}pcb temp=pcbs[minIndex];//交换pcbs[minIndex]=pcbs[i];pcbs[i]=temp;}}int selNectProcess()//下⼀个进程的选择,条件:等待状态&&运⾏时间最短{int result=-1;int minTime=100;for(int index=0; index<PNUMBER; index++){if(strcmp(pcbs[index].provessStatus,WAIT)==0)//进程处于等待状态{if(pcbs[index].runTime<minTime)//且运⾏时间最短{minTime=pcbs[index].runTime;result=index;}}}return result;//返回下⼀个运⾏的进程的编号}int isHasProcessArrive()//检查在某⼀个时间点有没有进程到达{int result=-1;for(int index=0; index<PNUMBER; index++){if(pcbs[index].arriveTime==currentTime)//某个进程的到达时间等于当前时间{result=index;strcpy(pcbs[index].provessStatus,WAIT);//改变进程状态}}return result;}void runProcess(int pindex){int runTime=pcbs[pindex].runTime;//进程开始,需要改变进程的相关信息pcbs[pindex].startTime=currentTime;pcbs[pindex].endTime=pcbs[pindex].startTime+pcbs[pindex].runTime;strcpy(pcbs[pindex].provessStatus,RUN);printfPcbsInfo();//输出此时进程的信息for(int k=1; k<=runTime; k++) //进程运⾏中{currentTime++;//时间转动isHasProcessArrive();if(k==runTime)//进程结束条件{//改变进程相关信息strcpy(pcbs[pindex].provessStatus,FINISH);pcbs[pindex].turnOverTime=pcbs[pindex].endTime-pcbs[pindex].arriveTime;pcbs[pindex].userweightTurnOverTime=pcbs[pindex].turnOverTime*1.0/pcbs[pindex].runTime; }printfPcbsInfo();//打印进程此时信息}processIndex++;//准备运⾏下⼀个进程currentTime--;//收回⼀个时刻,因为下⼀个进程在此时运⾏}void startProcess()//开始进程的调度{int firstArriveTime=pcbs[0].arriveTime;//第⼀个到达的进程int nextIndex=0;printfPcbsInfo();while(1){currentTime++;//时间流动isHasProcessArrive();//检查这个时候有没有新到达的进程if(currentTime<firstArriveTime)//第⼀个进程都没有到{printfPcbsInfo();}else if(currentTime==firstArriveTime){runProcess(0);//执⾏进程}else//第⼀个进程执⾏完毕,选择下⼀个进程{nextIndex=selNectProcess();if(nextIndex!=-1)//存在下⼀个将要执⾏的进程{runProcess(nextIndex);}if(processIndex==PNUMBER)//所有进程执⾏完毕break;//跳出循环}}}int main(){createPcbs();//进程相关信息的初始化sortPcbs();//进程按照到达时间升序排序startProcess();//开始进程的调度return0;}输⼊⽂本如下:运⾏结果如下:如果有不⾜错误的地⽅,欢迎⼤家拍砖指正哦天⽓不错。
短作业(过程)优先调度算法之青柳念文创作1.短作业(过程)优先调度算法SJ(P)F,是指对短作业或短过程优先调度的算法.它们可以分别用于作业调度和过程调度.短作业优先(SJF)的调度算法是从后备队列中选择一个或若干个估计运行时间最短的作业,将它们调入内存运行.而短过程(SPF)调度算法则是从停当队列中选出一个估计运行时间最短的过程,将处理机分配给它,使它当即执行并一直执行到完成,或发生某事件而被阻塞放弃处理机再重新调度.SJ(P)F调度算法能有效地降低作业(过程)的平均等待时间,提高系统吞吐量.该算法对长作业晦气,完全未思索作业的紧急程度.2.流程图3.代码#include<iostream.h>#include<string.h>#include<stdlib.h>struct sjf{char name[10];float arrivetime;float servicetime;float starttime;float finishtime;float zztime;float dqzztime;};sjf a[100];void input(sjf *p,int N){ int i;printf("intput the process's name & arrivetime & servicetime:\nfor exmple: a 0 100\n");for(i=0;i<=N1;i++){printf("input the %dth process's information:\n",i+1);scanf("%s%f%f",&p[i].name,&p[i].arrivetime ,&p[i].servicetime);}void Print(sjf *p,float arrivetime,float servicetime,float starttime,float finishtime,float zztime,float dqzztime,int N) {int k;printf("run order:");printf("%s",p[0].name);for(k=1;k<N;k++){printf(">%s",p[k].name);}printf("\nthe process's information:\n");printf("\nname\tarrive\tservice\tstart\tfinish \tzz\tdqzz\n");for(k=0;k<=N1;k++){ printf("%s\t%.2f\t%.2f\t%.2f\t%.2f\t%.2f\t%. 2f\t\n",p[k].name,p[k].arrivetime,p[k].service time,p[k].starttime,p[k].finishtime,p[k].zztim e,p[k].dqzztime);}//pai xuvoid sort(sjf *p,int N){for(int i=0;i<=N1;i++)for(int j=0;j<=i;j++)if(p[i].arrivetime<p[j].arrivetime){sjf temp;temp=p[i];p[i]=p[j];p[j]=temp;}}//yun xing jieduanvoid deal(sjf *p, float arrivetime,float servicetime,float starttime,float finishtime,float &zztime,float &dqzztime,int N) { int k;for(k=0;k<=N1;k++){if(k==0){p[k].starttime=p[k].arrivetime;p[k].finishtime=p[k].arrivetime+p[k].serviceti me;}else{p[k].starttime=p[k1].finishtime;p[k].finishtime=p[k1].finishtime+p[k].servicet ime;}}for(k=0;k<=N1;k++){p[k].zztime=p[k].finishtimep[k].arrivetime;p[k].dqzztime=p[k].zztime/p[k].servicetime;}}void sjff(sjf *p,int N){floatarrivetime=0,servicetime=0,starttime=0,finisht ime=0,zztime=0,dqzztime=0;sort(p,N);for(int m=0;m<N1;m++){if(m==0)p[m].finishtime=p[m].arrivetime+p[m].serviceti me;elsep[m].finishtime=p[m1].finishtime+p[m].servicet ime;int i=0;for(int n=m+1;n<=N1;n++){if(p[n].arrivetime<=p[m].finishtime)i++;}float min=p[m+1].servicetime;int next=m+1;//m+1=nfor(int k=m+1;k<m+i;k++){if(p[k+1].servicetime<min){min=p[k+1].servicetime;next=k+1;}}sjf temp;temp=p[m+1];p[m+1]=p[next];p[next]=temp;}deal(p,arrivetime,servicetime,starttime,finish time,zztime,dqzztime,N);Print(p,arrivetime,servicetime,starttime,finis htime,zztime,dqzztime,N);}int main(){ int N;printf("短作业优先调度算法\n");printf("input the process's number:\n");scanf("%d",&N);input(a,N);sjf *b=a;sjf *c=a;sjff(b,N);system("PAUSE");}4.运行成果5.心得体会课程设计竣事了,在这次的课程设计中不但检验了我所学习的知识,也培养了我如何去做一件事情,又如何完成一件事情的才能.通过摹拟过程的调度问题,更加深了我对于操纵系统实际的懂得,在自己的动手操纵过程中,可以体会成功的喜悦和遇到问题自己处理的才能,对于我来讲是一次提高,让自己多多的在实践中可以加深对实际的懂得,也让我大白了以后应该如何更好,更高效的学习,在以后,我会更加尽力.。
1. 有三个批处理作业,第一个作业10:00 到达,需要执行2 小时;第二个作业在10:10 到达,需要执行1 小时;第三个作业在10:25 到达,需要执行25 分钟。
分别采用先来先服务,短作业优先和最高响应比优先三种调度算法,各自的平均周转时间是多少?解:先来先服务:(结束时间=上一个作业的结束时间+执行时间周转时间=结束时间-到达时间=等待时间+执行时间)短作业优先:1)初始只有作业1,所以先执行作业1,结束时间是12:00,此时有作业2和3;2)作业3需要时间短,所以先执行;最高响应比优先:高响应比优先调度算法既考虑作业的执行时间也考虑作业的等待时间,综合了先来先服务和最短作业优先两种算法的特点。
1)10:00只有作业1到达,所以先执行作业1;2)12:00时有作业2和3,作业2:等待时间=12:00-10:10=110m;响应比=1+110/60=2.8;作业3:等待时间=12:00-10:25=95m,响应比=1+95/25=4.8;所以先执行作业32. 在一单道批处理系统中,一组作业的提交时刻和运行时间如下表所示。
试计算一下三种作业调度算法的平均周转时间T 和平均带权周转时间W。
(1)先来先服务;(2)短作业优先(3)高响应比优先解:先来先服务:短作业优先:作业顺序:1)8:00只有作业1,所以执行作业1;2)9:00有作业2和3,作业3短,所以先执行3;3)9:12有作业2和4,作业4短,所以先执行4;高响应比优先:作业顺序:1)8:00只有作业1,所以执行作业1;2)9:00有作业2和3作业2等待时间=9:00-8:30=30m,响应比=1+30/30=2;作业3等待时间=9:00-9:00=0m,响应比=1+0/12=1;所以执行作业2;3)9:30有作业3和4作业3等待时间=9:30-9:00=30m,响应比=1+30/12=3.5;作业4等待时间=9:30-9:06=24m,响应比=1+24/6=5;所以执行作业44)执行作业33.设系统中有3 种类型的资源(A,B,C)和5 个进程(P1,P2,P3,P4,P5),A 资源的数量为17, B 资源的数量为5, C 资源的数量为20。
实验报告【实验名称】实验一进程调度【实验目的】巩固和加深处理机调度的概念。
【实验内容】设计调度算法,模拟实现处理机的调度。
1.设计先来先服务调度算法数据结构和符号说明:typedef struct PCB{char name[10]; //进程名char state;//进程状态int arrivetime; //到达时间int starttime;//开始时间int finishtime; //完成时间int servicetime;//服务时间float turnaroundtime;//周转时间float weightedturnaroundtime;//带权周转时间struct PCB *next;//指向下个进程的指针}pcb;int time;//全局变量,计时器int n;//全局变量,进程个数pcb *head = NULL,*p,*q;//进程链表指针流程图:开始输入进程名、到达时间、服务时间存入链表进程是否全部处理完毕?当前进程状态是否为F ?N处理进程,计算完成时间,周转时间等,并更新当前时间Y处理下一进程N 结束Y 程序源代码/*操作系统实验一先来先服务调度算法*/#include<stdio.h>#include<stdlib.h>typedef struct PCB//进程控制{char name[10];//进程名char state;//进程状态int arrivetime;//到达时间int starttime;//开始时间int finishtime;//结束时间int servicetime;//服务时间float turnaroundtime;//周转时间float weightedturnaroundtime;//带权周转时间struct PCB *next;//指向下个进程}pcb;int time;//当前时间int n;//进程个数pcb *head = NULL,*p,*q;//处理未完成的进程void run_fcfs(pcb *p1){time = p1->arrivetime > time ? p1->arrivetime : time; //如果进程到达时间大于当前时间,则当前时间=到达时间p1->starttime = time;//当前时间即为进程开始时间printf("\n现在时间是%d,开始运行作业%s\n",time,p1->name);time += p1->servicetime;//进程开始处理,处理的时间为进程的服务时间p1->state = 'T';//更改状态,表示该进程已被处理过p1->finishtime = time;//存入完成时间p1->turnaroundtime = p1->finishtime - p1->arrivetime;//周转时间=完成时间-到达时间p1->weightedturnaroundtime = p1->turnaroundtime/p1->servicetime;//带权周转时间=周转时间/服务时间printf(" 到达时间服务时间开始时间完成时间周转时间带权周转时间\n");printf("%8d%10d%10d%10d%10.1f%14.2f\n",p1->arrivetime,p1->servicetime,p1->starttime,p1->finishtime,p1->turnaroundtime,p1->weightedturnaroundtime);//打印输出}//找到当前未完成的进程void fcfs(){int i,j;p = head;for(i=0; i<n; i++){if(p->state == 'F'){q = p;//如果当前进程未执行,则开始执行run_fcfs(q);}p = p->next;指向下一个进程}}//输入进程个数与进程信息void getInfo(){int num;printf("\n作业个数:");scanf("%d",&n);for(num = 0; num < n; num++){p = (pcb*)malloc(sizeof(pcb));printf("依次输入:\n");printf("进程名到达时间服务时间\n");scanf("%s\t%d\t%d",&p->name,&p->arrivetime,&p->servicetime);if(head == NULL){head = p;q = p;time = p->arrivetime;}if(p->arrivetime < time)time =p->arrivetime;q->next = p;p->starttime = 0;p->finishtime = 0;p->turnaroundtime = 0;p->weightedturnaroundtime = 0;p->next = NULL;p->state = 'F';q = p;}}int main(){printf("先来先服务调度算法\n");getInfo();p = head;fcfs();return 0;}运行结果图1运行结果2.设计按短进程优先调度算法数据结构与符号说明:struct sjf{char name[10]; //进程名float arrivetime; //到达时间float servicetime;//服务时间float starttime; //开始时间float finishtime;//完成时间float turnaroundtime;//周转时间float dqturnaroundtime;//带权周转};//结构体数组sjf a[100];流程图:程序源代码/*操作系统实验一按短进程优先调度算法*/#include <stdio.h>struct sjf{char name[10]; //进程名float arrivetime; //到达时间float servicetime;//服务时间float starttime; //开始时间float finishtime;//完成时间float turnaroundtime;//周转时间float dqturnaroundtime;//带权周转};//结构体数组sjf a[100];//输入函数void input(sjf *p,int N){int i;printf("依次输入:\n");for(i=0;i<=N-1;i++){printf("进程名到达时间服务时间\n");scanf("%s%f%f",&p[i].name,&p[i].arrivetime,&p[i].servicetime);}}//输出函数void Print(sjf *p,float arrivetime,float servicetime,float starttime,float finishtime,float turnaroundtime,float dqturnaroundtime,int N){int k;printf("\n进程名到达时间服务时间开始时间完成时间周转时间带权周转时间\n");for(k=0;k<=N-1;k++){printf("%4s%10.2f%10.2f%10.2f%10.2f%10.2f%10.2f\n",p[k].name,p[k].arrivetime,p[k].servicetime,p[k]. starttime,p[k].finishtime,p[k].turnaroundtime,p[k].dqturnaroundtime);}}//按到达时间排序void sort(sjf *p,int N){for(int i=0;i<=N-1;i++)for(int j=0;j<=i;j++)if(p[i].arrivetime<p[j].arrivetime){sjf temp;temp=p[i];p[i]=p[j];p[j]=temp;}}//处理作业void deal(sjf *p, float arrivetime,float servicetime,float starttime,float finishtime,float &turnaroundtime,float&dqturnaroundtime,int N){int k;for(k=0;k<=N-1;k++){if(k == 0){p[k].starttime = p[k].arrivetime;//第一个进程的开始时间=到达时间p[k].finishtime = p[k].arrivetime + p[k].servicetime;}//完成时间=到达时间+服务时间else{if(p[k-1].finishtime >= p[k].arrivetime){p[k].starttime = p[k-1].finishtime;}//前一项作业的完成时间大于当前项的到达时间则当前项的开始时间为前一项的结束时间else{p[k].starttime = p[k].arrivetime;//否则当前项的开始时间为当前项的到达时间}p[k].finishtime = p[k].starttime + p[k].servicetime;//完成时间=作业开始时间+作业服务时间}}for(k=0;k<=N-1;k++){p[k].turnaroundtime = p[k].finishtime - p[k].arrivetime;//周转时间=完成时间-到达时间p[k].dqturnaroundtime = p[k].turnaroundtime / p[k].servicetime;//带权周转时间=周转时间/服务时间}}//短作业优先调度算法void sjff(sjf *p,int N){float arrivetime = 0;float servicetime = 0;float starttime = 0;float finishtime = 0;float turnaroundtime = 0;float dqturnaroundtime = 0;sort(p,N);//调用sort函数进行排序for(int m=0;m<N-1;m++){if(m == 0)//第一项作业p[m].finishtime = p[m].arrivetime + p[m].servicetime;//完成时间=到达时间+服务时间else{if(p[m-1].finishtime >= p[m].arrivetime ){p[m].starttime = p[m-1].finishtime;}//上一项进程结束后本进程才开始else{p[m].starttime = p[m].arrivetime;}p[m].finishtime = p[m].starttime + p[m].servicetime;//完成时间=开始时间+服务时间}int i = 0;for(int n=m+1;n<=N-1;n++){if(p[n].arrivetime <= p[m].finishtime) i++;}//按服务时间排序float min=p[m+1].servicetime;int next=m+1;//m+1=nfor(int k=m+1;k<m+i;k++){if(p[k+1].servicetime<min)//k+1项的服务时间小于最小项则k+1项为最小项{min=p[k+1].servicetime;next=k+1;}}sjf temp;temp=p[m+1];p[m+1]=p[next];p[next]=temp;}deal(p,arrivetime,servicetime,starttime,finishtime,turnaroundtime,dqturnaroundtime,N);Print(p,arrivetime,servicetime,starttime,finishtime,turnaroundtime,dqturnaroundtime,N); }int main(){int N;printf("短作业优先调度算法\n");printf("\n作业个数:");scanf("%d",&N);input(a,N);sjf *b=a;sjff(b,N);//调用sjff函数}运行结果图2 运行结果。
四、计算题1.有以下三个作业,分别采用先来先服务和短作业优先作业调度算法。
试问它们的平均周转时间各是什么?是否还可以给出一种更好的调度算法,使其平均周转时间优于这两种调度算法?解:(1)采用先来先服务作业调度算法时的实施过程如下。
这时,作业的调度顺序是1→2→3。
其平均周转时间为:(8 + 11.6 + 12)/ 3 = 10.53 (2)采用短作业优先作业调度算法时的实施过程如下。
这里要注意,在作业1运行完毕进行作业调度时,作业2和3都已经到达。
由于是实行短作业优先作业调度算法,因此先调度作业3运行,最后调度作业2运行。
所以,这时的作业调度顺序是1→3→2。
其平均周转时间为:(8 + 8 + 12.6)/ 3 = 9.53(3)还可以有更好的作业调度算法,使其平均周转时间优于这两种调度算法。
例如,如果知道在作业1后面会来两个短作业,那么作业1到达后,先不投入运行。
而是等所有作业到齐后,再按照短作业优先作业调度算法进行调度,具体实施过程如下。
这时的作业调度顺序是3→2→1。
其平均周转时间为:(1 + 5.6 + 14)/ 3 = 6.87 2.有一组作业,它们的到达时间和所需CPU时间如下所示,分别采用先来先服务和短作业优先作业调度算法,给出它们的调度顺序、作业周转时间以及平均周转时间。
解:(1)采用先来先服务作业调度算法时的实施过程如下:这时,作业的调度顺序是1→2→3→4,其平均周转时间为:(70 + 60 + 60 + 45)/ 4 = 58.75 (2)采用短作业优先作业调度算法时的实施过程如下:这时,作业的调度顺序是1→4→3→2,其平均周转时间为:(70 + 5 + 35 + 75)/ 4 = 46.25三、简答题1.对临界区的管理应遵循哪些基本准则?答:为了合理利用临界资源,保证进程互斥地进入临界区,对临界区的管理应遵循以下准则:(1)空闲让进。
当无进程处于临界区时,表明临界资源处于空闲状态,应允许一个请求进入临界区的进程立即进入自己的临界区,以有效地利用临界资源。
短作业(进程)优先调度算法之迟辟智美创作1.短作业(进程)优先调度算法SJ(P)F,是指对短作业或短进程优先调度的算法.它们可以分别用于作业调度和进程调度.短作业优先(SJF)的调度算法是从后备队列中选择一个或若干个估计运行时间最短的作业,将它们调入内存运行.而短进程(SPF)调度算法则是从就绪队列中选出一个估计运行时间最短的进程,将处置机分配给它,使它立即执行并一直执行到完成,或发生某事件而被阻塞放弃处置机再重新调度.SJ(P)F调度算法能有效地降低作业(进程)的平均等候时间,提高系统吞吐量.该算法对长作业晦气,完全未考虑作业的紧迫水平.2.流程图3.代码#include<iostream.h>#include<string.h>#include<stdlib.h>struct sjf{char name[10];float arrivetime;float servicetime;float starttime;float finishtime;float zztime;float dqzztime;};sjf a[100];void input(sjf *p,int N){ int i;printf("intput the process's name & arrivetime & servicetime:\nfor exmple: a 0 100\n");for(i=0;i<=N1;i++){printf("input the %dth process's information:\n",i+1);scanf("%s%f%f",&p[i].name,&p[i].arrivetime,&p[i]. servicetime);}}void Print(sjf *p,float arrivetime,float servicetime,float starttime,float finishtime,float zztime,float dqzztime,int N){int k;printf("run order:");printf("%s",p[0].name);for(k=1;k<N;k++){printf(">%s",p[k].name);}printf("\nthe process's information:\n");printf("\nname\tarrive\tservice\tstart\tfinish\tzz\tdqzz\n");for(k=0;k<=N1;k++){ printf("%s\t%.2f\t%.2f\t%.2f\t%.2f\t%.2f\t%.2f\t\n",p[k] .name,p[k].arrivetime,p[k].servicetime,p[k].starttime,p[k]. finishtime,p[k].zztime,p[k].dqzztime);}}//pai xuvoid sort(sjf *p,int N){for(int i=0;i<=N1;i++)for(int j=0;j<=i;j++)if(p[i].arrivetime<p[j].arrivetime){sjf temp;temp=p[i];p[i]=p[j];p[j]=temp;}}//yun xing jieduanvoid deal(sjf *p, float arrivetime,float servicetime,float starttime,float finishtime,float &zztime,float &dqzztime,int N){ int k;for(k=0;k<=N1;k++){if(k==0){p[k].starttime=p[k].arrivetime;p[k].finishtime=p[k].arrivetime+p[k].servicetime;} else{p[k].starttime=p[k1].finishtime;p[k].finishtime=p[k1].finishtime+p[k].servicetime;} }for(k=0;k<=N1;k++){p[k].zztime=p[k].finishtimep[k].arrivetime;p[k].dqzztime=p[k].zztime/p[k].servicetime;}}void sjff(sjf *p,int N){floatarrivetime=0,servicetime=0,starttime=0,finishtime=0,zzti me=0,dqzztime=0;sort(p,N);for(int m=0;m<N1;m++){if(m==0)p[m].finishtime=p[m].arrivetime+p[m].servicetime;elsep[m].finishtime=p[m1].finishtime+p[m].servicetime;int i=0;for(int n=m+1;n<=N1;n++){if(p[n].arrivetime<=p[m].finishtime)i++;}float min=p[m+1].servicetime;int next=m+1;//m+1=nfor(int k=m+1;k<m+i;k++){if(p[k+1].servicetime<min){min=p[k+1].servicetime;next=k+1;}}sjf temp;temp=p[m+1];p[m+1]=p[next];p[next]=temp;}deal(p,arrivetime,servicetime,starttime,finishtime,zztime,d qzztime,N);Print(p,arrivetime,servicetime,starttime,finishtime,zztime, dqzztime,N);}int main(){ int N;printf("短作业优先调度算法\n");printf("input the process's number:\n");scanf("%d",&N);input(a,N);sjf *b=a;sjf *c=a;sjff(b,N);system("PAUSE");}4.运行结果5.心得体会课程设计结束了,在这次的课程设计中不单检验了我所学习的知识,也培养了我如何去做一件事情,又如何完成一件事情的能力.通过模拟进程的调度问题,更加深了我对把持系统理论的理解,在自己的入手把持过程中,能够体会胜利的喜悦和遇到问题自己解决的能力,对我来说是一次提高,让自己多多的在实践中可以加深对理论的理解,也让我明白了以后应该如何更好,更高效的学习,在以后,我会更加努力.。
短作业优先调度算法SJF算法的核心思想是最短作业先执行,这样可以最大化利用CPU资源,减少平均等待时间和作业的响应时间。
它适用于批处理系统和交互式系统。
SJF算法的实现包括两种方式:非抢占式和抢占式。
非抢占式SJF算法:在非抢占式SJF算法中,一旦CPU开始执行一个作业,它会一直执行完毕,直到作业完成或者发生I/O请求。
当一个新的作业到达时,系统会比较该作业的执行时间和当前正在执行的作业的剩余执行时间,如果新作业的执行时间较短,则优先执行新作业。
抢占式SJF算法:在抢占式SJF算法中,一旦有一个新的作业到达,并且它的执行时间比当前正在执行的作业短,操作系统会暂停当前作业的执行,将CPU分配给新作业,等新作业执行完毕后再继续执行之前的作业。
抢占式SJF算法需要操作系统具备抢占能力,即能够中断并恢复作业的执行。
SJF算法的优点是可以最大化利用CPU资源,减少平均等待时间和作业的响应时间,适用于CPU密集型的作业。
然而,SJF算法也存在一些问题和局限性:1.预测执行时间的困难:在实际系统中,很难准确预测一个作业的执行时间,因此SJF算法可能会出现误判,导致等待时间增加。
2.饥饿问题:如果有大量的短作业不断到达,长作业可能会一直等待。
这种情况称为饥饿问题,长作业可能无法获取足够的CPU时间,导致低响应性。
3.处理I/O请求的处理:SJF算法无法解决I/O请求的调度问题,因此需要结合其他算法来处理。
为了解决SJF算法存在的问题,还发展了一些改进的版本,如最短剩余时间优先算法(Shortest Remaining Time First, SRTF),该算法在抢占式的基础上,可以在作业执行过程中切换到更短的作业,以进一步减少等待时间。
总结起来,SJF算法是一种重要的进程调度算法,它按照作业的执行时间来确定优先级。
它的优点是可以最大化利用CPU资源,减少等待时间和作业响应时间。
然而,它也存在预测执行时间困难、饥饿问题和无法解决I/O请求的问题。
短作业优先算法例题
短作业优先算法(Shortest Job First Algorithm,SJF)是一种
资源调度算法,它以最短作业(或进程)的时间为基准来调度进程,
即将剩余未完成的进程中第一个就绪最短作业优先分配。
它可以用于
处理器调度、磁盘调度等多种资源控制。
SJF算法将所有等待的作业按照它们需要的运行时间从短到长的顺
序组成一个队列,当一个作业抵达后,它就被插入到队列中,在队列
的最前端则放置了需要最少运行时间的作业。
然后,当CPU由空闲变
成可用时,它就从队列的首元素开始选择作业来执行,即先加载最短
运行时间的作业,这样可以使整个系统更加有效地使用CPU,减少等待
时间和提高吞吐量。
总之,SJF算法的优点是显著减少了平均等待时间,但是它的缺点
也很明显:第一,要求系统具有对各作业运行时间的精确预测能力,
否则它无法正确排序;第二,有时候短作业也会受阻,因为它需要等
待更长作业的结束,这样就会增加空闲时间;第三,这种算法不能有
效地分配I/O资源。
下面为SJF算法例题:
假定系统中有4个作业A,B,C,D,它们的运行时间分别为3,3,2,4。
(1)如果采用先来先服务调度,则运行结果如下,平均周转时间为(12+7+4+4)/4=7.25
A -->
B -->
C --> D
时间: 0 3 6 8 12
(2)如果采用短作业优先算法,则运行结果如下,平均周转时间为(6+3+4+4)/4=4.5
C --> A --> B --> D
时间: 0 2 5 8 12。