其实就是限制了资源的总量,提交作业的时候要考虑是否满足资源。
在单道不考虑资源的基础上改了一下。 没什么亮点。
#coding=utf-8
import sys,random,time
"""
这是多道批处理 单cpu的作业调度,和单道处理不同的是,这里要考虑资源因素,如果
不能满足进程运行所需分配的空间,则不能提交处理。所以只要更改提交作业模块即可
"""
###################################################################################################
#tool
def GetName():
global nameI;
t=nameI;
nameI=chr(ord(nameI)+1)
return t
###################################################################################################
class jcb:
def __init__(self):
self.status='Wait'#Run Finish
self.name=GetName();
self.submitTime=random.randint(0,15)#提交作业的时间
self.needTime=random.randint(5,30) #所需运行的时间
self.resource=random.randint(5,20) #所需的资源
self.isAlive=False#是否被激活进入handlerJcb处理队列中,激活后应该变身为Wait状态
self.runtime=0
""""
#下面均为计算需要添加的变量 其实没啥用。
运行时刻、完成时刻、周转时间、带权周转时间,以及这组作业的平均周转时间及带权平均周转时间,
以比较各种算法的优缺点。
周转时间: 完成时间-提交作业的时间
平均周转时间= 周转时间/运行时间
"""
self.startTime=-1
self.endTime=-1
self.zzTime=-1# 周转时间
self.dqZzTime=-1.0#带权周转时间
###################################################################################################
#FCFS
class FCFSQueue:
def __init__(self):
self.q=[]
def insert(self,e):
"""
先来先服务算法,只要把新提交的作业放到等待队列的最后面就可以了
"""
self.q.append(e)
def pop(self):
t=self.q[0]
del self.q[0]
return t
def isEmpty(self):
return len(self.q)==0
###################################################################################################
#SJF
class SJFQueue:
def __init__(self):
self.q=[]
def insert(self,e):
"""
最短作业优先。其实就是一个优先级队列
这里的短当然就是时间短~
"""
if len(self.q)==0:
self.q.append(e)
else:
for i in range(len(self.q)):
if e.needTime<self.q[i].needTime:
break
self.q.insert(i,e)
def pop(self):
t=self.q[0]
del self.q[0]
return t
def isEmpty(self):
return len(self.q)==0
###################################################################################################
#HRN
class HRNQueue:
def __init__(self):
self.q=[]
def insert(self,e):
self.q.append(e)
def dynamicSort(self):
#响应比xyb
#xyb=1.0+e.waittime/e.needTime
#e.waittime=currentTime-e.submitTime
global hj
currentTime=hj.getCurrentTime()
self.q.sort(key=lambda x: 1.0+(0.0+currentTime-x.submitTime)/x.needTime,reverse=False)
"""
for i in range(len(self.q)):
t=self.q[i]
print 'name=%s,q=%f'%(t.name, 1.0+(0.0+currentTime-t.submitTime)/t.needTime)
"""
def pop(self):
self.dynamicSort()
t=self.q[0]
del self.q[0]
return t
def isEmpty(self):
return len(self.q)==0
###################################################################################################
class handleJob:
def __init__(self,kind):
q=kind+'Queue'
self.notSubmitQueue=produceJcbQueue()
self.WaitQueue=eval(q)()#等待运行的作业
self.runJcb=None#正在运行的作业
self.doneJcb=[]#运行结束的作业
self.currentTime=0;
self.solution=q # FCFS XXX XXX
#
self.resource=random.randint(20,40)#总资源
print u'总资源:',self.resource
def getCurrentTime(self):
return self.currentTime
def checkToSubmit(self):
i=0
while True:
if len(self.notSubmitQueue)==0 or i>=len(self.notSubmitQueue):
print 'no jobs to submit for now'
break
"""#这里是单道处理的版本 不需要考虑资源因素
t=self.notSubmitQueue[0]
if t.submitTime==self.currentTime:
del self.notSubmitQueue[0]
t.isAlive=True
t.status='Wait'
self.WaitQueue.insert(t)
print 'have submit job %s to cpu'%t.name
else:
break
"""
##这里是多道批处理版本
t=self.notSubmitQueue[i]
if t.submitTime<=self.currentTime:
if t.resource<=self.resource:
#此时该作业可以提交
del self.notSubmitQueue[i]
t.isAlive=True
t.status='Wait'
self.WaitQueue.insert(t)
#提交作业会消耗资源
self.resource-=t.resource
print u'使用资源:',t.resource
print u'剩余资源:',self.resource
print 'have submit job %s to cpu'%t.name
else:#并没有资源可以满足提交这个作业
i+=1
else:
#因为待提交作业是按时间排序的 如果发现一个超过当前时间的
#则表示之后的作业都还没到提交时间 即可break
break
def checkManageCPU(self):
##首先检查是否需要进行调度新的作业进来(是否可以运行新的作业,也就是cpu不存在作业或者作业刚好做完)
if self.runJcb==None or self.runJcb.runtime==self.runJcb.needTime:
#此时需要调度作业
#先将作业调度出队列
if self.runJcb!=None:
t=self.runJcb
t.status='Finish'
t.endTime=self.currentTime
t.zzTime=t.endTime-t.submitTime
t.dqZzTime=1.0*t.zzTime/t.needTime
self.doneJcb.append(t)
self.runJcb=None
#释放运行完的作业要恢复资源
self.resource+=t.resource
print u'释放资源:',t.resource
print u'剩余资源:',self.resource
print 'job %s finished and leave the cpu'%t.name
#如果有作业可以调度
if not self.WaitQueue.isEmpty():
t=self.WaitQueue.pop()
t.status='Run'
t.startTime=self.currentTime
self.runJcb=t
print "job %s starts to run"%t.name
else:
#如果不存在作业
print u'no jobs to dive in the cpu'
def run1s(self):
t=self.runJcb
if t!=None:
t.runtime+=1
print 'job %s have run %ds ,it needs %d seconds to complete'%(t.name,t.runtime,t.needTime)
else:
print 'no job runs in the cpu'
self.currentTime+=1
time.sleep(1)
def goOneSecond(self):
print u'第%d秒:'%self.currentTime
self.checkToSubmit()
self.checkManageCPU()
self.run1s()
def isNeedRun(self):
#print 't1:',len(self.notSubmitQueue)==0
#print 't2:',self.WaitQueue.isEmpty()
#print 't3:',self.runJcb==None
return not(len(self.notSubmitQueue)==0 and self.WaitQueue.isEmpty() and self.runJcb==None)
def displayEnding(self):
print u'到达时间 服务时间 开始执行时间 完成时间 周转时间 带权周转时间'
sumzzTime=0
sumdqzzTime=0.0
for i in range(len(self.doneJcb)):
t=self.doneJcb[i]
sumzzTime+=t.zzTime
sumdqzzTime+=t.dqZzTime
print "%3d %3d %3d %3d %3d %5.2f"%(t.submitTime,t.needTime,t.startTime,t.endTime,t.zzTime,t.dqZzTime)
print u"平均周转时间: %5.2f"%(sumzzTime*1.0/len(self.doneJcb))
print u"平均带权周转时间: %5.2f"%(sumdqzzTime*1.0/len(self.doneJcb))
def start(self):
"""
#因为不考虑作进程调度,又因为是单核cpu,所以作业调入cpu等到执行完才可以退出,
从而挑选下一个进程。代入Cpu执行
"""
print 'solution'+self.solution
while self.isNeedRun():
print '------------------------------------------------'
self.goOneSecond()
else:
print '------------------------------------------------'
print 'All Jobs Done'
print '------------------------------------------------'
self.displayEnding()
"""
应该分两部分处理 未提交的jcb队列控制 和提交后的jcb队列控制(也就是handlerJcb)
未提交队列应该有提交算法:也就是按时把作业提交给handlerJcb。其实它的作业就是激活一个作业,所以这部分可以写在handlerJcb里面
提交队列由handler控制有三种算法
"""
###################################################################################################
def init():
global nameI,jcbQueue
nameI='a';
def produceJcbQueue():
num=raw_input('How many job do you want?(suggested 3~5)\n>')
num=int(num,10)
print 'producing %d jcbs'%num
q=[]
#同时按照提交时间排序
for i in range(num):
t=jcb()
#q.append(t)
j=0
if len(q)!=0:
for j in range(len(q)):
if t.submitTime<q[j].submitTime:
q.insert(j,t)
break
else:
q.append(t)
else:
q.append(t)
print 'jcb '+t.name+':','submitTime=%d'%t.submitTime,'needTime=%d'%t.needTime,'resource=%d'%t.resource
while True:
c=raw_input('ok?(y/n/c)(c for look all the jcbQueue)')
if c=='n':sys.exit()
elif c=='c':
print '------------------------------------------------'
for i in range(len(q)):
t=q[i]
print 'jcb '+t.name+':','submitTime=%d'%t.submitTime,'needTime=%d'%t.needTime,'resource=%d'%t.resource
print '------------------------------------------------'
elif c=='y':
return q
"""
self.name=GetName();
self.submitTime=random.randint(0,15)#提交作业的时间
self.needTime=random.randint(5,30) #所需运行的时间
self.resource=random.randint(5,20) #所需的资源
"""
if __name__=="__main__":
print '-------------------------------'
print u'多道批处理版本'
print '-------------------------------'
global hj
print '1.FCFS'
print '2.SJF'
print '3.HRN'
c=raw_input('>')
choose={
'1':'FCFS',
'2':'SJF',
'3':'HRN'
}
if c not in choose.keys():
print 'exit'
sys.exit()
init()
hj=handleJob(choose[c])
raw_input('ok?')
hj.start()
print 'All Done'