1实验一先来先服务FCFS和短作业优先SJF进程调度算法
实验一先来先服务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):调试过程中遇到的问题以及解决方法,设计与实现的回顾讨论和分析;开始的时候没有判断进程是否到达,导致短进程优先算法运行结果错误,后来加上了判断语句后就解决了改问题。
(2):算法的性能分析及其改进设想;即使用户输入的进程到达时间没有先后顺序也能准确的计算出结果.(加循环,判断各个进程的到达时间先后,组成一个有序的序列)(3):经验和体会。
通过本次实验,深入理解了先来先服务和短进程优先进程调度算法的思想,培养了自己的动手能力,通过实践加深了记忆.五:用户使用说明在同一目录下的.txt文件中按输入要求输入相关数据,并且根据提示选择相应的算法。
六:测试结果测试数据:输出结果:七:附录源程序:#include<iostream>#include〈iomanip〉//格式化输出结果#include〈sstream〉//读取文件#include〈fstream> //读取文件using namespace std;const int MaxNum=100;int ArrivalTime[MaxNum];//到达时间int ServiceTime[MaxNum];//服务时间int FinishTime[MaxNum];//完成时间int WholeTime[MaxNum]; //周转时间double WeightWholeTime[MaxNum];//带权周转时间double AverageWT_FCFS,AverageWT_SJF;//平均周转时间double AverageWWT_FCFS,AverageWWT_SJF; //平均带权周转时间void FCFS(int n);//先来先服务void SJF(int n);//短作业优先void print(int n,int array[]);void print(int n,double array[]);void printproceed(int n); //输出FCFS进程运行状态void main(){int n,i,j; //n:进程数;i、j:循环计数变量ifstream in("text。
txt”);//读文件string s;for(i=0;i〈3,getline(in,s);i++){ //当i=0读入进程数n ;i=1读入各进程到达时间;i=2读入各进程服务时间istringstream sin(s);switch(i){case 0:sin>>n;break;case 1:for(j=0;j<n;j++)sin〉〉ArrivalTime[j];break;case 2:for(j=0;j〈n;j++)sin〉〉ServiceTime[j];break;}}//显示各进程数据cout〈<setfill(’’)<<setw(7)〈〈”进程名"〈<setw(1)<〈"";char ch=’A';for(i=0;i〈n;i++)cout〈<setw(3)〈<char(ch+i);cout〈<endl〈<”到达时间";for(i=0;i<n;i++)cout〈〈setw(3)<〈ArrivalTime[i];cout<<endl〈〈"服务时间”;for(i=0;i<n;i++)cout〈〈setw(3)<〈ServiceTime[i];cout〈〈endl;//选择算法:先来先服务FCFS—->1 短作业优先SJF——>2 关闭-—>0cout<〈”请选择算法:FCFS——>1 SJF-—>2 退出-—〉0”〈<endl〈〈”选择:";int choice;cin>>choice;while(choice!=0) //直到输入值为0跳出循环,结束程序{while(choice!=1 &&choice !=2 && choice!=0 ){cout〈<”Please enter 0,1 or 2!"〈〈endl;cin>〉choice;}if(choice==0)return;if(choice==1)FCFS(n);//进行先来先服务FCFS算法elseSJF(n);//进行短作业优先服务SJF算法cout〈<endl〈<"请选择: FCFS-->1 SJF—-〉2 退出-—>0"<<endl<<"选择:";cin>〉choice;}return;}//———--———-—-—--——-—先来先服务------———--—---——————-—-———-——--—-————--void FCFS(int n){//第一个进程先服务FinishTime[0]=ArrivalTime[0]+ServiceTime[0];WholeTime[0]=FinishTime[0]-ArrivalTime[0];WeightWholeTime[0]=double(WholeTime[0])/double(ServiceTime[0]);for(int i=1;i〈n;i++){if(FinishTime[i-1]〉ArrivalTime[i])FinishTime[i]=FinishTime[i-1]+ServiceTime[i];//如果上一个进程的完成时间大于下一个进程的到达时间,//那么下一个进程的开始时间从上一个进程的完成时间开始elseFinishTime[i]=ArrivalTime[i]+ServiceTime[i];//否则,下一个进程的开始时间从它本身的到达时间开始WholeTime[i]=FinishTime[i]—ArrivalTime[i];WeightWholeTime[i]=double(WholeTime[i])/double(ServiceTime[i]);}double totalWT=0,totalWWT=0;for(int j=0;j<n;j++){ //循环累加,求总的周转时间,总的带权周转时间totalWT+=WholeTime[j];totalWWT+=WeightWholeTime[j];}AverageWT_FCFS=totalWT/double(n);AverageWWT_FCFS=totalWWT/double(n);//输出各结果cout<<"—-—-—-—-—先来先服务FCFS——-—--—--—----"〈<endl;cout〈〈"完成时间分别为:";print(n,FinishTime);cout<〈"周转时间分别为:”;print(n,WholeTime);cout〈〈"带权周转时间分别为:”;print(n,WeightWholeTime);cout〈〈"平均周转时间:”<<AverageWT_FCFS<〈endl;cout<〈"平均带权周转时间:”<〈AverageWWT_FCFS<〈endl;printproceed(n);}//———-————-—--—-————短作业优先——-——-—----————————-——-—-—-——---void SJF(int n){int Short;//存放当前最短作业的序号int Finish=0; //存放当前完成时间double totalWT=0,totalWWT=0;for(int a=0;a<n;a++)//初始化完成时间为0FinishTime[a]=0;int i; //循环计数累加变量for(i=0;i〈n;i++){int tag=0;//用于标记当前完成时间内,是否找到短作业int Max=10000;for(int j=0;j<n;j++){if(FinishTime[j]==0 && ArrivalTime[j]〈=Finish &&ServiceTime[j]<=Max){Max=ServiceTime[j];Short=j;tag=1;}}if(tag==1){//找到短作业FinishTime[Short]=Finish+ServiceTime[Short];}if(tag==0){ //未找到for(int k=0;k〈n,FinishTime[k]==0;k++){//直接进入下一未完成进程Short=k;break;}FinishTime[Short]=ArrivalTime[Short]+ServiceTime[Short];}Finish=FinishTime[Short];}for(i=0;i〈n;i++){ //计算周转时间、带权周转时间WholeTime[i]=FinishTime[i]—ArrivalTime[i];WeightWholeTime[i]=double(WholeTime[i])/double(ServiceTime[i]);}for(int j=0;j<n;j++){ //计算总的周转时间、总的带权周转时间totalWT+=WholeTime[j];totalWWT+=WeightWholeTime[j];}AverageWT_FCFS=totalWT/double(n);AverageWWT_FCFS=totalWWT/double(n);//输出各值cout<〈"-——-—-—--短作业优先SJF—----—--——----"<〈endl;cout〈〈”完成时间:”;print(n,FinishTime);cout<〈”周转时间:”;print(n,WholeTime);cout<〈"带权周转时间:”;print(n,WeightWholeTime);cout〈〈”平均周转时间:"<〈AverageWT_FCFS<〈endl;cout<〈"平均带权周转时间:"<<AverageWWT_FCFS〈〈endl;printproceed(n);}void print(int n,int array[]){ //打印int型数组for(int i=0;i〈n;i++)cout〈<array[i]〈<””;cout〈<endl;}void print(int n,double array[]){//打印double型数组for(int i=0;i〈n;i++)cout〈〈array[i]〈〈””;cout<〈endl;}void printproceed(int n){ //打印各时刻各进程的运行情况char ch='A’;for(int i=0;i〈n;i++){int StartTime=FinishTime[i]—ServiceTime[i];cout<<"时刻”〈〈StartTime<<":进程"〈〈char(ch+i)〈<”开始运行"<〈endl;cout<〈”时刻”<<FinishTime[i]〈〈":进程"〈<char(ch+i)〈<"停止运行”〈〈endl;}}。
进程调度模拟算法
进程调度模拟算法进程调度是操作系统中的重要组成部分之一,它负责决定在多道程序环境下,哪个进程将获得CPU的使用权。
进程调度模拟算法是为了研究和评估不同调度策略的性能而开发的一种仿真方法。
在实际系统中,调度算法会受到多种因素的影响,如进程优先级、进程的I/O需求、进程的实际执行时间等。
通过模拟这些因素,可以更好地理解不同调度算法之间的差异,并选择最合适的算法来满足特定需求。
下面介绍两种常见的进程调度模拟算法:先来先服务(FCFS)和最短作业优先(SJF)算法。
1. 先来先服务(FCFS)算法:该算法按照进程到达的顺序来调度任务。
当一个进程完成或阻塞时,下一个已到达的进程将获得CPU的使用权。
这种算法非常简单,但是不适用于长作业时间和短作业时间交替出现的情况。
在短作业启动时,长作业仍然在运行,使得短作业的等待时间增加。
2. 最短作业优先(SJF)算法:该算法根据任务的执行时间来调度进程。
在该算法中,每个进程的执行时间都是已知的,并且操作系统根据已知的执行时间来决定哪个进程获得CPU的使用权。
在短作业优先算法中,短作业将会先被调度,这样有助于减少平均周转时间和等待时间。
但是,短作业优先算法容易产生“饥饿”现象,即长作业可能会一直等待,而短作业一直得到CPU的使用权。
除了以上两种算法,还有其他的进程调度模拟算法。
例如:- 时间片轮转(RR)调度算法:使用固定的时间片来调度进程,当时间片用完后,该进程被放入就绪队列的末尾。
- 优先级调度算法:每个进程都拥有一个优先级,优先级越高的进程越早被调度。
这种方法可以根据不同进程的紧迫程度和重要性来进行调度。
- 多级反馈队列调度算法:将就绪队列划分为多个队列,并根据进程的性质和优先级将进程放入不同的队列。
每个队列都有不同的优先级和时间片大小,进程可以通过提高优先级或时间片大小来提高被调度的机会。
在实际应用中,需要根据系统需求和性能指标选择合适的调度算法。
常用的性能指标包括平均周转时间、平均等待时间、CPU利用率等。
用于作业调度的算法
用于作业调度的算法作业调度是计算机操作系统中的一个重要概念,它指的是在多个进程同时运行时,如何合理地分配CPU资源,使得系统能够高效地完成各项任务。
作业调度算法是实现作业调度的关键,下面将详细介绍几种常见的作业调度算法。
一、先来先服务(FCFS)算法先来先服务(FCFS)算法是最简单也是最容易实现的一种作业调度算法。
该算法按照进程到达时间的顺序依次执行,即当一个进程到达后,如果当前没有正在执行的进程,则立即执行该进程;否则将该进程加入等待队列中,并等待前面所有进程执行完毕后再进行处理。
FCFS算法优点在于简单易实现,并且保证了公平性。
但由于没有考虑到不同进程的优先级和执行时间等因素,因此可能会导致长任务等待时间过长、短任务响应时间过长等问题。
二、短作业优先(SJF)算法短作业优先(SJF)算法是一种根据作业长度进行排序的调度策略。
该算法按照各个进程需要占用CPU时间片长度进行排序后依次执行,即当一个新的进程到达时,如果其需要占用的时间片长度比当前正在执行的进程短,则立即切换到该进程进行处理,否则将该进程加入等待队列中,并等待前面所有进程执行完毕后再进行处理。
SJF算法优点在于能够最大限度地缩短作业响应时间,提高系统的吞吐量。
但由于需要预测每个进程需要占用的时间片长度,因此实现起来较为困难,并且可能会出现“饥饿”现象,即长时间等待CPU资源的进程无法得到及时处理。
三、优先级调度算法优先级调度算法是一种按照不同进程的优先级进行排序的调度策略。
该算法将每个进程赋予一个优先级值,根据优先级值高低依次执行,即当一个新的进程到达时,如果其优先级比当前正在执行的进程高,则立即切换到该进程进行处理,否则将该进程加入等待队列中,并等待前面所有优先级更高的进程执行完毕后再进行处理。
优先级调度算法可以根据不同任务类型和紧急性进行灵活调整,并且可以避免长任务等待时间过长、短任务响应时间过长等问题。
但由于可能会出现“饥饿”现象和优先级反转等问题,因此需要进行适当的优化和调整。
常用的调度算法
常用的调度算法调度算法是指操作系统中用于决定进程何时执行、何时暂停等的一种算法。
常用的调度算法包括先来先服务(FCFS)、短作业优先(SJF)、优先级调度、时间片轮转等。
下面将对这些常用的调度算法进行详细介绍。
一、先来先服务(FCFS)先来先服务是最简单的调度算法之一,它按照进程到达的顺序进行调度,即谁先到谁先执行。
这种算法容易实现,但是存在“饥饿”现象,即如果某个进程长时间等待,则其他进程可能会一直占用CPU资源,导致该进程无法得到执行。
因此,在实际应用中,FCFS很少被使用。
二、短作业优先(SJF)短作业优先是一种以作业运行时间为依据的调度算法。
它通过预测每个进程需要运行的时间,并将其按照运行时间从小到大排序,然后依次执行。
这种算法可以最大限度地减少平均等待时间和平均周转时间,并且不会出现“饥饿”现象。
但是,在实际应用中,由于很难准确预测每个进程需要运行的时间,因此SJF也存在缺陷。
如果预测不准确,那么就会出现长作业等待短作业的情况,导致长作业的等待时间变长。
三、优先级调度优先级调度是一种按照进程优先级进行调度的算法。
每个进程都有一个优先级,系统会根据进程的优先级来决定下一个要执行的进程。
通常情况下,优先级越高的进程越有可能得到CPU资源。
但是,如果某个进程的优先级一直比其他进程高,那么其他进程就会一直等待,导致“饥饿”现象。
此外,在实际应用中,由于不同进程之间的优先级差别较大,因此可能会导致低优先级的进程长时间等待。
四、时间片轮转时间片轮转是一种按照时间片进行调度的算法。
它将CPU资源划分成若干个时间片,并将每个时间片分配给一个正在运行或等待运行的进程。
当一个进程用完了它所分配到的时间片后,系统会将其挂起,并将CPU资源分配给下一个等待运行的进程。
这种算法可以避免“饥饿”现象,并且能够保证所有正在运行或等待运行的进程都能够得到CPU资源。
但是,如果时间片太小,会导致进程频繁切换,影响系统性能;如果时间片太大,会导致长作业等待时间变长。
先来先服务FCFS和短作业优先SJF进程调度算法
先来先服务FCFS和短作业优先SJF进程调度算法FCFS(先来先服务)算法是最简单的进程调度算法之一、它按照进程到达的顺序来分配CPU时间,即先到达的进程先执行。
在FCFS算法中,进程按照它们进入就绪队列的时间排序,随后按照就绪队列的顺序被调度执行。
FCFS算法不考虑进程的执行时间,也不会对进程进行任何优先级排序。
FCFS算法的优点是简单易懂,实现起来非常简单。
但是,FCFS算法有一个明显的缺点是不利于短进程的执行。
当一个长进程到达并占据CPU 资源时,短进程可能要等待很长时间才能执行。
这种情况下,CPU的利用率会较低,响应时间也会较长。
因此,FCFS算法适用于进程的执行时间相对较短且没有明显的优先级关系的场景。
SJF(短作业优先)算法是根据进程的执行时间进行优先级排序的进程调度算法。
在SJF算法中,短进程将会优先执行,而长进程需等待。
当一个进程到达就绪队列时,系统会根据其估计的执行时间大小将其插入到就绪队列的适当位置。
当前执行的进程完成后,下一个执行的是就绪队列中估计执行时间最短的进程。
SJF算法的优点是能够减少平均等待时间,提高系统整体的吞吐量。
由于短进程占用CPU时间较少,因此能够更快地释放CPU资源给其他进程使用,从而减少等待时间。
然而,SJF算法存在一个问题是如何准确估计进程的执行时间。
在实际场景中,准确估计进程的执行时间是很困难的,因此SJF算法很容易出现估计错误,导致长进程等待时间过长。
总结来说,FCFS和SJF都是进程调度算法,但它们有不同的特点和适用场景。
FCFS算法简单易懂,适用于进程执行时间相对较短且没有明显优先级的场景;而SJF算法适用于进程执行时间有较大差异的场景,能够减少平均等待时间。
然而,SJF算法对进程的执行时间要求较高,需要准确估计执行时间,否则可能导致长进程等待时间过长。
在实际应用中,通常会根据具体情况选择不同的调度算法。
例如,在交互式系统中,为了提供更好的用户体验,使用SJF算法能够减少响应时间;而在批处理系统中,FCFS算法通常被用于处理较短的作业。
调度算法C语言实现
调度算法C语言实现调度算法是操作系统中的重要内容之一,它决定了进程在系统中的运行方式和顺序。
本文将介绍两种常见的调度算法,先来先服务(FCFS)和最短作业优先(SJF),并用C语言实现它们。
一、先来先服务(FCFS)调度算法先来先服务(FCFS)调度算法是最简单的调度算法之一、它按照进程到达的先后顺序进行调度,即谁先到达就先执行。
实现这个算法的关键是记录进程到达的顺序和每个进程的执行时间。
下面是一个用C语言实现先来先服务调度算法的示例程序:```c#include <stdio.h>//进程控制块结构体typedef structint pid; // 进程IDint arrivalTime; // 到达时间int burstTime; // 执行时间} Process;int maiint n; // 进程数量printf("请输入进程数量:");scanf("%d", &n);//输入每个进程的到达时间和执行时间Process process[n];for (int i = 0; i < n; i++)printf("请输入进程 %d 的到达时间和执行时间:", i);scanf("%d%d", &process[i].arrivalTime,&process[i].burstTime);process[i].pid = i;}//根据到达时间排序进程for (int i = 0; i < n - 1; i++)for (int j = i + 1; j < n; j++)if (process[i].arrivalTime > process[j].arrivalTime) Process temp = process[i];process[i] = process[j];process[j] = temp;}}}//计算平均等待时间和平均周转时间float totalWaitingTime = 0; // 总等待时间float totalTurnaroundTime = 0; // 总周转时间int currentTime = 0; // 当前时间for (int i = 0; i < n; i++)if (currentTime < process[i].arrivalTime)currentTime = process[i].arrivalTime;}totalWaitingTime += currentTime - process[i].arrivalTime;totalTurnaroundTime += (currentTime + process[i].burstTime) - process[i].arrivalTime;currentTime += process[i].burstTime;}//输出结果float avgWaitingTime = totalWaitingTime / n;float avgTurnaroundTime = totalTurnaroundTime / n;printf("平均等待时间:%f\n", avgWaitingTime);printf("平均周转时间:%f\n", avgTurnaroundTime);return 0;```以上程序实现了先来先服务(FCFS)调度算法,首先根据进程的到达时间排序,然后依次执行每个进程,并计算总等待时间和总周转时间。
作业调度算法(先来先服务算法,短作业算法)
题目:作业调度算法班级:网络工程姓名:朱锦涛学号:E一、实验目的用代码实现页面调度算法,即先来先服务(FCFS)调度算法、短作业优先算法、高响应比优先调度算法。
通过代码的具体实现,加深对算法的核心的理解。
二、实验原理1.先来先服务(FCFS)调度算法FCFS是最简单的调度算法,该算法既可用于作业调度,也可用于进程调度。
当在作业调度中采用该算法时,系统将按照作业到达的先后次序来进行调度,或者说它是优先考虑在系统中等待时间最长的作业,而不管该作业所需执行的时间的长短,从后备作业队列中选择几个最先进入该队列的作业,将它们调入内存,为它们分配资源和创建进程。
然后把它放入就绪队列。
2.短作业优先算法SJF算法是以作业的长短来计算优先级,作业越短,其优先级越高。
作业的长短是以作业所要求的运行时间来衡量的。
SJF算法可以分别用于作业和进程调度。
在把短作业优先调度算法用于作业调度时,它将从外存的作业后备队列中选择若干个估计运行时间最短的作业,优先将它们调入内存。
3、高响应比优先调度算法高响应比优先调度算法则是既考虑了作业的等待时间,又考虑了作业的运行时间的算法,因此既照顾了短作业,又不致使长作业等待的时间过长,从而改善了处理机调度的性能。
如果我们引入一个动态优先级,即优先级是可以改变的令它随等待的时间的延长而增加,这将使长作业的优先级在等待期间不断地增加,等到足够的时间后,必然有机会获得处理机。
该优先级的变化规律可以描述为:优先权 = (等待时间 + 要求服务时间)/要求服务时间三、实验内容源程序:#include<>#include<>#include<>struct work{i nt id;i nt arrive_time;i nt work_time;i nt wait;f loat priority;typedef struct sjf_work{s truct work s_work; d = rand()%10;w[i].arrive_time = rand()%10;w[i].work_time = rand()%10+1;}f or(j=0;j<5;j++){printf("第%d个作业的编号是:%d\t",j+1,w[j].id);printf("第%d个作业到达时间:%d\t",j+1,w[j].arrive_time);printf("第%d个作业服务时间:%d\t",j+1,w[j].work_time);printf("\n");for(j=1;j<5;j++)for(k=0;k<5-j;k++){if(w[k].arrive_time > w[k+1].arrive_time) {temp = w[k];w[k] = w[k+1];w[k+1] = temp;}}printf("\n");w_finish_time[0] = w[0].arrive_time +w[0].work_time;for(j=0;j<5;j++){if(w_finish_time[j] < w[j+1].arrive_time){w_finish_time[j+1] = w[j+1].arrive_time + w[j+1].work_time;}elsew_finish_time[j+1] = w_finish_time[j] +w[j+1].work_time;}for(j=0;j<5;j++)w_rel_time[j] = w_finish_time[j] -w[j].arrive_time;for(j=0;j<5;j++){rel_time += w_rel_time[j];}for(j=0;j<5;j++){printf("第%d个系统执行的作业到达时间:%d ",j+1,w[j].arrive_time);printf("编号是:%d ",w[j].id);printf("服务时间是:%d ",w[j].work_time);printf("完成时间是:%d ",w_finish_time[j]);printf("周转时间是:%d ",w_rel_time[j]);printf("\n");}printf("平均周转时间:%f\n",rel_time/5); }void SJF(){i nt w_rel_time[10];i nt w_finish_time[10];f loat rel_time = 0;s rand(time(0));i nt i;i nt j = 0;P NODE pHead = (PNODE)malloc(sizeof(NODE));i f (NULL == pHead){printf("分配失败, 程序终止!\n");exit(-1);P NODE pTail = pHead;p Tail->pNext = NULL; 来先服务算法该算法严格按照各作业到达时间来为其分配进程和资源,实验的结果见截图,最后算出该算法五个作业的平均周转时间。
几种操作系统调度算法
几种操作系统调度算法操作系统调度算法是操作系统中用于确定进程执行的顺序和优先级的一种方法。
不同的调度算法有不同的优缺点,适用于不同的场景和需求。
下面将介绍几种常见的操作系统调度算法:1.先来先服务(FCFS)调度算法:先来先服务调度算法是最简单的调度算法之一、按照进程到达的顺序进行调度,首先到达的进程先执行,在CPU空闲时执行下一个进程。
这种算法实现简单,并且公平。
但是,由于没有考虑进程的执行时间,可能会导致长作业时间的进程占用CPU资源较长时间,从而影响其他进程的响应时间。
2.短作业优先(SJF)调度算法:短作业优先调度算法是根据进程的执行时间进行排序,并按照执行时间最短的进程优先执行。
这种算法可以减少平均等待时间,提高系统的吞吐量。
然而,对于长作业时间的进程来说,等待时间会相对较长。
3.优先级调度算法:优先级调度算法是根据每个进程的优先级来决定执行顺序的。
优先级可以由用户设置或者是根据进程的重要性、紧迫程度等因素自动确定。
具有较高优先级的进程将具有更高的执行优先级。
这种算法可以根据不同情况进行灵活调度,但是如果不恰当地设置优先级,可能会导致低优先级的进程长时间等待。
4.时间片轮转(RR)调度算法:时间片轮转调度算法将一个固定的时间片分配给每个进程,当一个进程的时间片用完时,将该进程挂起,调度下一个进程运行。
这种算法可以确保每个进程获得一定的CPU时间,提高系统的公平性和响应速度。
但是,对于长时间运行的进程来说,可能会引起频繁的上下文切换,导致额外的开销。
5.多级反馈队列(MFQ)调度算法:多级反馈队列调度算法将进程队列划分为多个优先级队列,每个队列有不同的时间片大小和优先级。
新到达的进程被插入到最高优先级队列,如果进程在时间片内没有完成,则被移到下一个较低优先级队列。
这种算法可以根据进程的执行表现自动调整优先级和时间片,更好地适应动态变化的环境。
以上是几种常见的操作系统调度算法,每种算法都有其优缺点和适用场景。
作业调度算法先来先服务算法短作业算法页
作业调度算法: 先来先服务算法、短作业优先算法引言在计算机操作系统中,作业调度算法是一种重要的技术,用于管理和调度计算机系统中的作业。
作业调度算法决定了如何分配计算机资源,以便最大化系统的效率和吞吐量。
本文将介绍两种常见的作业调度算法:先来先服务算法(First Come First Serve,FCFS)和短作业优先算法(Shortest Job First,SJF)。
先来先服务算法(FCFS)先来先服务算法是最简单的作业调度算法之一。
按照作业提交的顺序进行调度,先提交的作业先执行,后提交的作业则等待。
这种调度算法不考虑作业的执行时间或优先级,只根据作业提交的先后顺序来进行调度。
算法流程1.将作业按照提交的先后顺序排列。
2.按照排列顺序执行作业。
优点•算法实现简单,易于理解和实现。
•适用于短作业或者作业提交顺序代表了作业的优先级的情况。
缺点•短作业可能因为长作业的存在而等待时间过长,导致响应时间较长。
•不考虑作业执行时间,可能导致平均等待时间和平均周转时间较长。
•无法适应不同作业的执行时间需求。
短作业优先算法(SJF)短作业优先算法是一种将作业按照执行时间长度进行排序的作业调度算法。
在短作业优先算法中,最短执行时间的作业先执行,以此类推。
该算法可以最大程度地减少作业的等待时间和周转时间。
算法流程1.将作业按照执行时间长度从短到长进行排序。
2.按照排列顺序执行作业。
优点•可以最大程度地减少作业的等待时间和周转时间。
•适用于短作业和长作业相互混合的情况。
缺点•难以准确估计作业的执行时间,可能导致长作业等待时间过长。
•需要预先知道作业的执行时间长度才能进行排序。
•不适用于长作业占主导地位的情况。
性能对比与选择先来先服务算法和短作业优先算法都有其优点和缺点。
选择合适的算法取决于具体的应用场景和需求。
•如果作业都很短,并且没有严格的截止时间要求,先来先服务算法可以简单高效地满足需求。
•如果作业的执行时间非常重要,并且具有较严格的截止时间要求,短作业优先算法可以最大程度地减少作业的等待时间和周转时间。
先来先服务和短作业优先调度算法
先来先服务调度算法和短作业优先调度算法
作业
提交 时间
运行 时间
开始 时间
1 8.00 2.00 8.00
1 8.00 2.00 8.00
2 8.50 0.50 10.00
2 8.50 0.50 10.30
3 9.00 0.10 10.50
3 9.00 0.10 10.00
4 9.50 0.20 10.60
可有效降低作业/进程的平均等待时间。 4
SJ(P)F缺点:
(1) 该算法对长作业不利,如作业C的周转时间由10增 至16,其带权周转时间由2增至3.1。更严重的是,如果有 一长作业(进程)进入系统的后备队列(就绪队列),由于调度 程序总是优先调度那些(即使是后进来的)短作业(进程),将 导致长作业(进程)长期不被调度。(不利长作业)
(2) 该算法完全未考虑作业的紧迫程度,因而不能保证 紧迫性作业(进程)会被及时处理。(不及时)
(3) 由于作业(进程)的长短只是根据用户所提供的估计 执行时间而定的,而用户又可能会有意或无意地缩短其作 业的估计运行时间,致使该算法不一定能真正做到短作业 优先调度。(不完全可靠)
5
调度算法练习题
6
4 9.50 0.20 10.10
先来先服务调度算法
平均周转时间
t = 1.725
平均带权周转时间 w = 6.875
完成 周转 带权周转 执行 时间 时间 时间 顺序
10.00 2.00
1
1
10.00 2.00
1
1
10.50 2.00
4
2
10.80 2.30 4.6
4
10.60 1.60 16
3
10.10 1.10 11
作业调度算法(先来先服务算法,短作业算法)
《操作系统》实验报告题目:作业调度算法班级:网络工程姓名:朱锦涛学号:E31314037一、实验目的用代码实现页面调度算法,即先来先服务(FCFS)调度算法、短作业优先算法、高响应比优先调度算法。
通过代码的具体实现,加深对算法的核心的理解。
二、实验原理1.先来先服务(FCFS)调度算法FCFS是最简单的调度算法,该算法既可用于作业调度,也可用于进程调度。
当在作业调度中采用该算法时,系统将按照作业到达的先后次序来进行调度,或者说它是优先考虑在系统中等待时间最长的作业,而不管该作业所需执行的时间的长短,从后备作业队列中选择几个最先进入该队列的作业,将它们调入内存,为它们分配资源和创建进程。
然后把它放入就绪队列。
2.短作业优先算法SJF算法是以作业的长短来计算优先级,作业越短,其优先级越高。
作业的长短是以作业所要求的运行时间来衡量的。
SJF算法可以分别用于作业和进程调度。
在把短作业优先调度算法用于作业调度时,它将从外存的作业后备队列中选择若干个估计运行时间最短的作业,优先将它们调入内存。
3、高响应比优先调度算法高响应比优先调度算法则是既考虑了作业的等待时间,又考虑了作业的运行时间的算法,因此既照顾了短作业,又不致使长作业等待的时间过长,从而改善了处理机调度的性能。
如果我们引入一个动态优先级,即优先级是可以改变的令它随等待的时间的延长而增加,这将使长作业的优先级在等待期间不断地增加,等到足够的时间后,必然有机会获得处理机。
该优先级的变化规律可以描述为:优先权 = (等待时间 + 要求服务时间)/要求服务时间三、实验内容源程序:#include<stdio.h>#include<stdlib.h>#include<time.h>struct work{i nt id;i nt arrive_time;i nt work_time;i nt wait;f loat priority;};typedef struct sjf_work{s truct work s_work; //数据域s truct sjf_work * pNext; //指针域}NODE,*PNODE;void FCFS();void SJF();void showmenu();bool Is_empty(PNODE pHead);int cnt_work(PNODE pHead);PNODE do_work(PNODE pHead,int *w_finish_time,int i);void show(int *w_finish_time,int i,PNODE q,int*w_rel_time);void HRRN();PNODE priorit(PNODE pHead);void do_work_1(PNODE pHead,int *w_finish_time,int i);int main(){i nt choice; //设置选择数s howmenu(); //显示菜单s canf("%d",&choice);w hile(choice != 0) //选择算法{switch(choice){case 1 :printf("您选择的是先来先服务算法:\n");FCFS();break;case 2 :printf("您选择的是短作业优先算法:\n");SJF();break;case 3 :printf("您选择的是高响应比优先调度算法\n");HRRN();break;default:printf("请重新选择!");break;}printf("\n");printf("下面是菜单,请继续,或者按‘0’退出"); showmenu();scanf("%d",&choice);}p rintf("感谢您使用本系统,再见!");r eturn 0;}void FCFS(){i nt j,k;i nt w_rel_time[5];i nt w_finish_time[5];f loat rel_time = 0;struct work temp;i nt i;s truct work w[5];s rand(time(0));f or(i=0;i<5;i++){w[i].id = rand()%10;w[i].arrive_time = rand()%10;w[i].work_time = rand()%10+1;}f or(j=0;j<5;j++){printf("第%d个作业的编号是:%d\t",j+1,w[j].id);printf("第%d个作业到达时间:%d\t",j+1,w[j].arrive_time);printf("第%d个作业服务时间:%d\t",j+1,w[j].work_time);printf("\n");}for(j=1;j<5;j++)for(k=0;k<5-j;k++){if(w[k].arrive_time > w[k+1].arrive_time){temp = w[k];w[k] = w[k+1];w[k+1] = temp;}}printf("\n");w_finish_time[0] = w[0].arrive_time + w[0].work_time;for(j=0;j<5;j++){if(w_finish_time[j] < w[j+1].arrive_time){w_finish_time[j+1] = w[j+1].arrive_time + w[j+1].work_time;}elsew_finish_time[j+1] = w_finish_time[j] +w[j+1].work_time;}for(j=0;j<5;j++)w_rel_time[j] = w_finish_time[j] -w[j].arrive_time;for(j=0;j<5;j++){rel_time += w_rel_time[j];}for(j=0;j<5;j++){printf("第%d个系统执行的作业到达时间:%d ",j+1,w[j].arrive_time);printf("编号是:%d ",w[j].id);printf("服务时间是:%d ",w[j].work_time);printf("完成时间是:%d ",w_finish_time[j]);printf("周转时间是:%d ",w_rel_time[j]);printf("\n");}printf("平均周转时间:%f\n",rel_time/5);}void SJF(){i nt w_rel_time[10];i nt w_finish_time[10];f loat rel_time = 0;s rand(time(0));i nt i;i nt j = 0;P NODE pHead = (PNODE)malloc(sizeof(NODE));i f (NULL == pHead){printf("分配失败, 程序终止!\n");exit(-1);}P NODE pTail = pHead;p Tail->pNext = NULL; //定义该链表有头结点,且第一个节点初始化为空f or(i=0;i<10;i++){PNODE pNew = (PNODE)malloc(sizeof(NODE));if (NULL == pNew){printf("分配失败, 程序终止!\n");exit(-1);}pNew->s_work.id = rand()%100;pNew->s_work.arrive_time = rand()%10;pNew->s_work.work_time = rand()%10+1;pTail->pNext = pNew;pNew->pNext = NULL;pTail = pNew;}P NODE p = pHead->pNext; //p指向第一个节点w hile (NULL != p){printf("第%d个作业的编号是:%d\t",j+1,p->s_work.id);printf("第%d个作业到达时间:%d\t",j+1,p->s_work.arrive_time);printf("第%d个作业服务时间:%d\t",j+1,p->s_work.work_time);printf("\n");p = p->pNext;printf("\n");j++;}p = pHead->pNext;P NODE q = p; //p,q都指向第一个节点p = p->pNext;w hile(p != NULL){if(p->s_work.arrive_time < q->s_work.arrive_time)q = p;p = p->pNext;}P NODE r = pHead->pNext; //r也指向第一个节点i nt cnt = 0; //记录所有节点数据域中到达时间最短且相等的个数w hile(r!= NULL){if( r->s_work.arrive_time == q->s_work.arrive_time ) cnt++;r = r->pNext;}p = pHead->pNext;w hile(p != NULL) //在相等到达时间的作业中找服务时间最短的作业{if(cnt > 1){if( p->s_work.arrive_time ==q->s_work.arrive_time )if( p->s_work.work_time < q->s_work.work_time )q = p;p = p->pNext;}elsep =NULL;} //确定q所指作业最先到达且服务时间最短w_finish_time[0] = q->s_work.arrive_time +q->s_work.work_time;w_rel_time[0] = w_finish_time[0] -q->s_work.arrive_time;p rintf("第1个系统执行的作业到达时间:%d",q->s_work.arrive_time);p rintf("编号是:%d ",q->s_work.id);p rintf("服务时间是:%d \n",q->s_work.work_time); p rintf("完成时间是:%d ",w_finish_time[0]);p rintf("周转时间是:%d \n",w_rel_time[0]);p = pHead; //寻找q的前一个节点,方便删掉q节点w hile( p->pNext != q ){p = p->pNext;}p->pNext = q->pNext;f ree(q);q = NULL;f or(i=0;i<9&&!Is_empty(pHead);i++){printf("现在系统还剩%d个作业!\n",cnt_work(pHead));q = do_work(pHead,w_finish_time,i);show(w_finish_time,i,q,w_rel_time);p = pHead; //寻找q的前一个节点,方便删掉q节点while( p->pNext != q ){p = p->pNext;}p->pNext = q->pNext;free(q);q = NULL;}f or(j=0;j<10;j++)rel_time += w_rel_time[j];}printf("平均周转时间:%f\n",rel_time/10);}bool Is_empty(PNODE pHead) //判断作业是否做完{P NODE p;p = pHead->pNext;i nt len = 0;w hile(p != NULL){len++;p = p->pNext;}i f(len == 0)return true; //当没有作业时,返回为真e lsereturn false;}int cnt_work(PNODE pHead) //计算当前还剩多少作业{P NODE p;p = pHead->pNext;i nt len = 0;w hile(p != NULL){len++;p = p->pNext;}r eturn len;}PNODE do_work(PNODE pHead,int *w_finish_time,int i) {P NODE p,q;i nt cnt = 0; //计数器清0,计算当前作业完成时,系统中有多少个作业已经到达p = pHead->pNext;q = p;w hile(p != NULL){if( p->s_work.arrive_time <= w_finish_time[i] ){cnt ++;q = p;p = p->pNext;}else{p = p->pNext;}} //q指向当前到达时间小于刚刚完成的作业,但不一定是服务时间最短的(如果有的话)p rintf("系统中有%d个作业在当前作业完成时已经到达!\n",cnt);p = pHead->pNext;w hile(p != NULL){if(cnt>1) //执行此次判断后,q现在指向所有条件都满足的作业(如果有的话){if( p->s_work.arrive_time <= w_finish_time[i] ){if( p->s_work.work_time < q->s_work.work_time ){q = p;p = p->pNext;}elsep = p->pNext;}elsep = p->pNext;}else //当前作业完成时,没有作业到达的情况{p = p->pNext; //用q来接收最先到达的,用p来遍历while( p != NULL ){if( p->s_work.arrive_time<q->s_work.arrive_time )q = p;p = p->pNext;}w_finish_time[i+1] = q->s_work.arrive_time + q->s_work.work_time;}}w_finish_time[i+1] = w_finish_time[i] +q->s_work.work_time;r eturn q;}void show(int *w_finish_time,int i,PNODE q,int*w_rel_time){w_finish_time[i+1] = w_finish_time[i] +q->s_work.work_time;w_rel_time[i+1] = w_finish_time[i+1] -q->s_work.arrive_time;p rintf("第%d个系统执行的作业到达时间:%d",i+2,q->s_work.arrive_time);p rintf("编号是:%d ",q->s_work.id);p rintf("服务时间是:%d\n",q->s_work.work_time);p rintf("完成时间是:%d ",w_finish_time[i+1]);p rintf("周转时间是:%d \n",w_rel_time[i+1]);}void showmenu(){printf("**********************************\n"); p rintf("请选择你要执行的命令~: \n");p rintf("1:先来先服务算法\n");p rintf("2:短作业优先算法\n");p rintf("3: 高响应比优先算法\n");p rintf("0: 退出菜单\n");p rintf("**********************************\n"); }void HRRN(){i nt w_rel_time[10];i nt w_finish_time[10];f loat rel_time = 0;f loat priority; //计算优先权s rand(time(0));i nt i;i nt j = 0;P NODE pHead = (PNODE)malloc(sizeof(NODE));i f (NULL == pHead){printf("分配失败, 程序终止!\n");exit(-1);}P NODE pTail = pHead;p Tail->pNext = NULL; //定义该链表有头结点,且第一个节点初始化为空f or(i=0;i<10;i++) //定义了十个进程{PNODE pNew = (PNODE)malloc(sizeof(NODE));if (NULL == pNew){printf("分配失败, 程序终止!\n");exit(-1);}pNew->s_work.id = rand()%100;pNew->s_work.arrive_time = rand()%10;pNew->s_work.work_time = rand()%10+1;pTail->pNext = pNew;pNew->pNext = NULL;pTail = pNew;}P NODE p = pHead->pNext; //p指向第一个节点w hile (NULL != p){printf("第%d个作业的编号是:%d\t",j+1,p->s_work.id);printf("第%d个作业到达时间:%d\t",j+1,p->s_work.arrive_time);printf("第%d个作业服务时间:%d\t",j+1,p->s_work.work_time);printf("\n");p = p->pNext;printf("\n");j++;}p = pHead->pNext;P NODE q = p; //p,q都指向第一个节点p = p->pNext;w hile(p != NULL){if(p->s_work.arrive_time < q->s_work.arrive_time) q = p;p = p->pNext;}P NODE r = pHead->pNext; //r也指向第一个节点i nt cnt = 0; //记录所有节点数据域中到达时间最短且相等的个数w hile(r!= NULL){if( r->s_work.arrive_time == q->s_work.arrive_time ) cnt++;r = r->pNext;}p = pHead->pNext;w hile(p != NULL) //在相等到达时间的作业中找服务时间最短的作业{if(cnt > 1){if( p->s_work.arrive_time ==q->s_work.arrive_time )if( p->s_work.work_time < q->s_work.work_time )q = p;p = p->pNext;}elsep =NULL;} //确定q所指作业最先到达且服务时间最短w_finish_time[0] = q->s_work.arrive_time +q->s_work.work_time;w_rel_time[0] = w_finish_time[0] -q->s_work.arrive_time;p rintf("第1个系统执行的作业到达时间:%d",q->s_work.arrive_time);p rintf("编号是:%d ",q->s_work.id);p rintf("服务时间是:%d \n",q->s_work.work_time); p rintf("完成时间是:%d ",w_finish_time[0]);p rintf("周转时间是:%d \n",w_rel_time[0]);p = pHead; //寻找q的前一个节点,方便删掉q节点w hile( p->pNext != q ){p = p->pNext;}p->pNext = q->pNext;f ree(q);q = NULL; //已经找到并执行第一个进程,执行完之后又将其删除了f or(i=0;i<9&&!Is_empty(pHead);i++){printf("现在系统还剩%d个作业!\n",cnt_work(pHead));do_work_1(pHead,w_finish_time,i);q = priorit(pHead);show(w_finish_time,i,q,w_rel_time);p = pHead; //寻找q的前一个节点,方便删掉q节点while( p->pNext != q ){p = p->pNext;}p->pNext = q->pNext;free(q);q = NULL;}f or(j=0;j<10;j++){rel_time += w_rel_time[j];}printf("平均周转时间:%f\n",rel_time/10);}void do_work_1(PNODE pHead,int *w_finish_time,int i) {P NODE p,q;i nt cnt = 0; //计数器清0,计算当前作业完成时,系统中有多少个作业已经到达p = pHead->pNext;q = p;w hile(p != NULL){if( p->s_work.arrive_time <= w_finish_time[i] ){cnt ++;q = p;p = p->pNext;}else{p = p->pNext;}} //q指向当前到达时间小于刚刚完成的作业,但有可能有另外几个进程也已经到达了,所以要进行下面的判断p rintf("系统中有%d个作业在当前作业完成时已经到达!\n",cnt);p = pHead->pNext;w hile(p != NULL){if(cnt>1) //说明此时有好几个都已经到达了{if(p->s_work.arrive_time <= w_finish_time[i]){p->s_work.wait = w_finish_time[i] -p->s_work.arrive_time;p = p->pNext;}else{p->s_work.wait = 0;p = p->pNext;}}else //当前作业完成时,没有作业到达的情况{p = p->pNext; //此时p指向第一个节点,q指向第二个节点,还是找最先到达的while( p != NULL ){if( p->s_work.arrive_time <q->s_work.arrive_time )q = p;p = p->pNext;}w_finish_time[i+1] = q->s_work.arrive_time +q->s_work.work_time;return;}}w_finish_time[i+1] = w_finish_time[i] +q->s_work.work_time;}PNODE priorit(PNODE pHead){P NODE p = pHead->pNext;w hile(p != NULL){if(p->s_work.wait > 0){p->s_work.priority = (p->s_work.wait +p->s_work.work_time) / p->s_work.work_time; //计算每一个已经等待的进程的优先等级p = p->pNext;}elsep = p->pNext;}p = pHead->pNext;P NODE q;q = p;p = p->pNext; //p已经指向第二个节点w hile(p != NULL){if(p->s_work.wait > 0){if(p->s_work.priority > q->s_work.priority){q = p;p = p->pNext;}elsep = p->pNext;}elsep = p->pNext;}p rintf("该进程优先级最高,为:%f\n",q->s_work.priority);return q;}实验结果:系统自动为每个算法模拟分配五个作业,同时随机生成作业的编号,作业的到达时间,作业估计运行的时间。
