1 实验目的
分析处理器实施进程调度的前提条件,理解并掌握各类处理器调度算法设计原理和实现机制。
2 实验内容
分析和探索处理器实施进程调度的前提条件,理解并掌握处理器调度算法的设计原理和实现机制,随机发生和模拟进程创建及相关事件,编程实现基于特定处理器调度算法(三种以上,譬如先来先服务调度算法、短进程优先算法、高优先权优先调度算法、高响应比优先调度算法、时间片轮转调度算法、多级反馈队列调度算法、等等)的系统调度处理过程并加以测试验证。
3 实验要求
本实验课题主要功能设计要求包括:
1)选取和设计实现三种以上的处理器调度算法;
2)针对特定的处理器调度算法,分析处理器实施进程调度的前提条件和要求(譬如进程创建时刻、运 行时间长短、各集中计算运行/输入输出操作时间段长短、优先级),并随机发生和模拟处理对应的进 程创建及相关时间;
3)编程实现处理器调度机制,针对特定的处理器调度算法和随机事件序列,给出相应的调度处理过 程,主要涵盖进程相关时间、处理器调度操作或处理措施以及各状态进程列表;
4)测试验证处理器调度机制的有效性及有关处理器调度算法设计方案的正确性。
4 实验设计
4.1 随机生成模拟进程
该实验调度算法都采用python进行模拟,使用函数processList(num)生成模拟进程列表。主要使用python random模块随机生成进程到达时间,进程相对结束时间这两个数值。生成各进程参数如图注释所示。
使用processShow(process)函数显示当前生成的进程列表,显示结果如图所示。

4.2 先来先服务调度算法
先来先服务调度算法是最基本的调度算法,核心是采用队列来实现。它根据进程到达时间决定先运行哪一个进程。这里我们使用list来实现。如下图所示,fcfs对模拟进程列表按时间到达先后进行排序。
算法主体使用while循环来模拟,cputime模拟时间,代码大体梗概如图所示,需要注意的是,status函数用来输出当前进程列表状态,conclusion函数用于模拟结束后输出统计结果。
Status函数:
Conclusion函数:
程序的main函数如图所示,通过传参将模拟方法与模拟进程数目传入。
Fcfs调度算法模拟结果如图所示:

4.3 短进程优先调度算法
短进程优先调度算法是在先来先服务调度算法的基础上,对就绪进程所需要处理时间进行排序,优先服务短进程。所以模拟该调度算法也是在fcfs算法的基础上进行的,sjf算法新增加了对就绪队列排序的功能,使用sjfSort(process,current)函数实现,函数如图所示,使用选择排序对就绪进程队列按处理时间长短进行排序。
模拟结果如图所示:

4.4 时间片轮转调度算法
时间片轮转调度算法的系统其进程就绪队列按照先来先服务调度原则,但是占用处理机只要一个时间片,在完成一个时间片后如果还没有完成就必须释放给下一个就绪的进程,而被剥夺的进程排到队尾。该算法最核心的便是时间片,在模拟程序中,我们将时间片长度设置为2s,while循环主体如图所示,与上两种算法有些不同,fcfs和sjf实现机制是普通队列,而rr调度算法实现机制是循环队列。
RR调度算法运行结果如图所示:

4.5 高响应比优先调度算法
高响应比优先调度算法的基本思想是把CPU分配给就绪队列中响应比最高的进程。既考虑作业的执行时间也考虑作业的等待时间,综合了先来先服务和最短作业优先两种算法的特点。所以该代码大体也与sjf算法相似,不同的是排序的依据,hrrn算法通过计算响应比来对就绪进程排序。排序算法如图所示:
HRRN算法运行结果如图所示:

4.6 调度算法简单比较
为了更好的体现各调度算法的特点,将模拟进程数设置为100.
FCFS算法:
SJF算法:
HRRN算法:
RR算法:
由于模拟生成的进程每一次程序运行都不一样,所以这里只简单分析各个算法点。
对于FCFS算法,100个模拟进程的带权周转时间,如果计算它们的方差,一定是特别大的。稳定性较差。
对于SJF算法和HRRN算法,各进程的带权周转时间在这里没有体现较大的差异,呈现出随到达时间增长进程的带权周转时间也增长的特点。猜测是random函数设置区间范围太小的原因。
最后对于RR算法,大体上各进程带权周转时间相近似,所以有比较好的稳定性。但是平均带权周转时间会有所增加。
5 实验总结
经过此次试验,对于操作系统的一些调度算法有了较为深刻的理解。对各调度算法的优点和缺点都有所了解,从而意识到了操作系统调度算法对于操作系统的重要性。
import random,sys# 生成进程列表def processList(num):process=[]for i in range(num):dic={}dic['id']=i #模拟进程号dic['start']=random.randint(0,20) #进程到达时间dic['end']=dic['start']+random.randint(1,20) #进程相对结束时间dic['runtime']=dic['end']-dic['start'] #进程所需运行时间dic['status']="" #进程当前状态dic['left']=dic['runtime'] #进程运行剩余时间dic['wait_time']=0 #进程等待时间dic['tr_time']=0 #进程周转时间process.append(dic)return process# 展示进程列表def processShow(process):for p in process:print(p)print()# 展示当前状态def status(process):print("-----status table-------")for p in process:print("process id:%d status:%s"%(p['id'],p['status']))print()# 计算进程状态时间def conclusion(process):print("-------------conclusion table--------------")print("进程ID 等待时间 周转时间 带权周转时间|")sum1=0sum2=0sum3=0.0for p in process:wait_time=p['wait_time']sum1+=wait_timetr_time=p['tr_time']sum2+=tr_timewtr_time=float(p['tr_time'])/(p['end']-p['start'])sum3+=wtr_timeprint("%3d %3ds %3ds %5.2f |"%(p['id'],p['wait_time'],p['tr_time'],wtr_time))print("-------------------------------------------")print("平均等待时间: %ds\n平均周转时间: %ds\n平均带权周转时间:%.2fs"%(sum1/len(process),sum2/len(process),sum3/len(process)))print("-------------------------------------------")# 非抢占式就绪排序def sjfSort(process,current):for i in range(current,len(process)):min=ifor j in range(current+1,len(process)):if process[i]['status'] =='就绪' and process[j]['status']=='就绪':if process[min]['runtime']>process[j]['runtime']:min=jprocess[min],process[i]=process[i],process[min]return process# 高响应比排序def hrrnSort(process,current,cputime):for i in range(current,len(process)):min=ifor j in range(current+1,len(process)):if process[i]['status'] =='就绪' and process[j]['status']=='就绪':scale_j=float(cputime-process[j]['start']+process[j]['runtime'])/process[j]['runtime']scale_min=float(cputime-process[min]['start']+process[min]['runtime'])/process[min]['runtime']if scale_j>scale_min:min=jprocess[min],process[i]=process[i],process[min]return process# 先来先服务算法def FCFS(process):print("-------------------------------FCFS-----------------------------")process=sorted(process,key=lambda x:x['start'])processShow(process)cputime=0current=0while True:flag=Falseif process[0]['start']==cputime:process[current]['runtime']+=cputimeprocess[current]['status']="运行"process[current]['wait_time']=cputime-process[current]['start']print("第"+str(cputime)+ "s"+"进程"+str(process[current]['id'])+"开始!")flag=True#当前进程结束if current<=len(process) and process[current]['runtime']==cputime and process[current]['status']=='运行':print("第"+str(cputime)+ "s"+"进程"+str(process[current]['id'])+"结束!")process[current]['status']='Die'process[current]['tr_time']=cputime-process[current]['start']flag=True#所有进程结束if process[current]['status']=='Die' and current==len(process)-1:print("所有进程执行完毕,总计耗时"+str(cputime)+"s")conclusion(process)break;#新进程开始if process[current]['status']=='Die' and process[current+1]['start']<=cputime:current+=1process[current]['runtime']+=cputimeprocess[current]['status']="运行"process[current]['wait_time']=cputime-process[current]['start']print("第"+str(cputime)+ "s"+"进程"+str(process[current]['id'])+"开始!")flag=True#检查是否有新进程到达for i in range(current+1,len(process)):if process[i]['start'] == cputime:process[i]['status'] = "就绪"if flag:status(process)cputime+=1# 非抢占式短作业优先算法def SJF(process):print("-------------------SJF------------------------------------")process=sorted(process,key=lambda x:x['start'])processShow(process)cputime=0current=0while True:flag=Falseif process[0]['start']==cputime:process[current]['runtime']+=cputimeprocess[current]['status']="运行"process[current]['wait_time']=cputime-process[current]['start']print("第"+str(cputime)+ "s"+"进程"+str(process[current]['id'])+"开始!")flag=Trueif current<=len(process) and process[current]['runtime']==cputime:print("第"+str(cputime)+ "s"+"进程"+str(process[current]['id'])+"结束!")process[current]['status']='Die'process[current]['tr_time']=cputime-process[current]['start']flag=Trueif process[current]['status']=='Die' and current==len(process)-1:print("所有进程执行完毕,总计耗时"+str(cputime)+"s")conclusion(process)break;if process[current]['status']=='Die' and process[current+1]['start']<=cputime:current+=1process[current]['runtime']+=cputimeprocess[current]['status']="运行"process[current]['wait_time']=cputime-process[current]['start']print("第"+str(cputime)+ "s"+"进程"+str(process[current]['id'])+"开始!")flag=Truefor i in range(current+1,len(process)):if process[i]['start'] == cputime:process[i]['status'] = "就绪"process=sjfSort(process,current+1)if flag:status(process)cputime+=1# 时间片轮询调度算法def RR(process):print("-------------------RR------------------------------------")process=sorted(process,key=lambda x:x['start'])processShow(process)cputime=0time_slice=2current=0start=Truewhile True:flag=Falseif start:if time_slice==0:time_slice==2if process[0]['start']==cputime:process[0]['status']='运行'print("第"+str(cputime)+ "s"+"进程"+str(process[0]['id'])+"开始!")flag=Truestart=False#当前进程运行结束if process[current]['status']=='运行' and process[current]['left']==0:print("第"+str(cputime)+ "s"+"进程"+str(process[current]['id'])+"结束!")process[current]['status']='Die'process[current]['tr_time']=cputime-process[current]['start']process[current]['wait_time']=process[current]['tr_time']-process[current]['runtime']flag=Truesig=True#启用新进程或所有进程结束if process[current]['status']=='Die':for i in range(current+1,current+len(process)):if process[i%len(process)]['status']=='就绪':process[i%len(process)]['status']='运行'current=i%len(process)print("第"+str(cputime)+ "s"+"进程"+str(process[current]['id'])+"开始!")sig=Falseflag=Truebreakif sig:sig=Truefor i in range(len(process)):if process[i]['status']!='Die':sig=Falsebreakif sig:status(process)print("所有进程执行完毕,总计耗时"+str(cputime)+"s")conclusion(process)breakif time_slice==0:time_slice=2#时间片结束,切换进程执行if (not start) and time_slice==0:process[current]['status']='就绪'time_slice=2for i in range((current+1)%len(process),(current+len(process))+1):if process[i%len(process)]['status']=='就绪':process[i%len(process)]['status']='运行'current=i%len(process)print("第"+str(cputime)+ "s"+"进程"+str(process[current]['id'])+"开始!")flag=Truebreakfor i in range(current+1,len(process)):if process[i]['start'] == cputime:process[i]['status'] = "就绪"if flag:status(process)cputime+=1if not start:process[current]['left']-=1time_slice-=1# 高响应比优先算法def HRRN(process):print("-------------------HRRN------------------------------------")process=sorted(process,key=lambda x:x['start'])processShow(process)cputime=0current=0while True:flag=Falseif process[0]['start']==cputime:process[current]['runtime']+=cputimeprocess[current]['status']="运行"process[current]['wait_time']=cputime-process[current]['start']print("第"+str(cputime)+ "s"+"进程"+str(process[current]['id'])+"开始!")flag=Trueif current<=len(process) and process[current]['runtime']==cputime:print("第"+str(cputime)+ "s"+"进程"+str(process[current]['id'])+"结束!")process[current]['status']='Die'process[current]['tr_time']=cputime-process[current]['start']flag=Trueif process[current]['status']=='Die' and current==len(process)-1:print("所有进程执行完毕,总计耗时"+str(cputime)+"s")conclusion(process)break;if process[current]['status']=='Die' and process[current+1]['start']<=cputime:current+=1process[current]['runtime']+=cputimeprocess[current]['status']="运行"process[current]['wait_time']=cputime-process[current]['start']print("第"+str(cputime)+ "s"+"进程"+str(process[current]['id'])+"开始!")flag=Truefor i in range(current+1,len(process)):if process[i]['start'] == cputime:process[i]['status'] = "就绪"process=hrrnSort(process,current+1,cputime)if flag:status(process)cputime+=1if __name__=="__main__":if len(sys.argv)<3:print("need more parameter!")exit()process=processList(int(sys.argv[2]))cmd=sys.argv[1].upper()if cmd=="FCFS":FCFS(process)elif cmd=="SJF":SJF(process)elif cmd=="RR":RR(process)elif cmd=="HRRN":HRRN(process)else:print("unknown command!")
