操作系统实验-进程控制(python实现)

操作系统实验-进程控制(python实现)

一、实验目标

模拟操作系统对进程的管理。实现进程之间的切换。

二、实验要求

(1)单处理机,即一次只能 1 个进程处于运行态
(2)内核实现进程切换和进程调度(scheduler&switch)的执行时间忽略,只考虑进程的执行所花时间
(3)程序的指令分为 cpu 和 io 两种类型。 cpu 代表 cpu 指令,执行 cpu 指令需要 1 个时间单位;io 代表 io 指令,需要阻塞该进程,执行 io 指令需要 5 个时间单位(第 1 个时间单位使用 cpu,后面 4 个时间单位使用 IO 设备)
(4)进程的状态有:READY,RUN:cpu, RUN:io, WAITING, DONE
(5)CPU 的状态有:1(忙),0(空闲),IOs 的状态有:1(忙),0(空闲)

三、代码实现

class PCB:                  #进程pcb
    def __init__(self,id):  #通过id来区分是哪一个进程
        self.id=id          #进程id
        self.state='ready'  #进程初始状态均设置为ready就绪态
        self.instruction=[] #进程的指令
        self.waitingtime=0  #阻塞标记 io时使用
        
class queue:                #用于进程调度管理的链式队列
    def __init__(self):
        self.head=None      #初始化赋空值
        self.tail=None
        self.size=0
    def isnotempty(self):   #判断队列是否为空
        if(self.head):      #队列非空返回1
            return 1
        else:               #队列为空返回0
            return 0
    def insert(self,node):  #插入一个新节点 尾插
        node.next=None
        if(self.head==None):#队列为空插入新节点
            self.head=node
        else:               #队列非空插入新节点
            self.tail.next=node
        self.tail=node
        self.size+=1        
    def remove(self):       #将节点从队列取出 同时移出当前队列
        node=self.head
        #self.size-=1
        self.head=self.head.next
        if self.isnotempty()==0 :
            self.tail=None
        return node
    
def go():
    readyqueue=queue()
    runningProcess=queue()
    waitingqueue=queue()
    pid0=PCB('PID0')
    pid1=PCB('PID1')
    pid2=PCB('PID2')
    pid3=PCB('PID3') 
    pid4=PCB('PID4')
    pid5=PCB('PID5')
    pid0.instruction=['io','cpu','cpu','io','cpu']
    pid1.instruction=['cpu','io','cpu']
    pid2.instruction=['io','cpu','cpu','io','io']
    pid3.instruction=['io','cpu','io']
    pid4.instruction=['cpu','io','cpu','io']
    pid5.instruction=['cpu','cpu','cpu','io']
    readyqueue.insert(pid0)
    readyqueue.insert(pid1)
    readyqueue.insert(pid2)
    readyqueue.insert(pid3)
    readyqueue.insert(pid4)
    readyqueue.insert(pid5)
    time=0
    cputime=0
    iotime=0
    print('Time   ',pid0.id,'      ',pid1.id,'      ',pid2.id,'      ',pid3.id,'      ',pid4.id,'      ',pid5.id,'      ','CPU     IOs')
    while readyqueue.isnotempty() or runningProcess.isnotempty() or waitingqueue.isnotempty():
        usecpu=0
        useio=0
        if runningProcess.isnotempty():
            rh=runningProcess.head
            if len(rh.instruction)==0:
               rh.state='done'
               runningProcess.remove()
        if waitingqueue.isnotempty():
            wh=waitingqueue.head
            while wh!=None:
                wh.state='waiting'
                wh.waitingtime-=1
                wh=wh.next
            wh=waitingqueue.head
            while wh!=None:
                if wh.waitingtime==-1:
                    if len(wh.instruction):
                        if runningProcess.isnotempty()==0:
                            runningProcess.insert(waitingqueue.remove())
                        else:
                            readyqueue.insert(waitingqueue.remove())
                    else:
                        wh.state='done'
                        waitingqueue.remove()
                wh=wh.next
        useio=waitingqueue.size
        if readyqueue.isnotempty():
            reh=readyqueue.head
            while reh!=None :
                reh.state='ready'
                reh=reh.next
        if runningProcess.isnotempty()==0 and readyqueue.isnotempty():
            runningProcess.insert(readyqueue.remove())
        if runningProcess.isnotempty():
            rh=runningProcess.head
            if len(rh.instruction):
                order=rh.instruction[0]
                if order=='cpu' :
                    rh.state='run:cpu'
                    del rh.instruction[0]
                    usecpu+=1
                elif order=='io' :
                    rh.state='run:io'
                    rh.waitingtime=4
                    del rh.instruction[0]
                    waitingqueue.insert(runningProcess.remove())
                    usecpu+=1
            else:
                rh.state='done'
                runningProcess.remove()
        time+=1
        print(time,' ',pid0.state,' ',pid1.state,' ',pid2.state,' ',pid3.state,' ',pid4.state,' ',pid5.state,' ',usecpu,' ',useio,sep='\t')
        if usecpu!=0 :
            cputime+=1
        if useio!=0 :
            iotime+=1
    print('Stats: Total Time ',time)
    print('Stats: CPU Busy ',cputime,' (',cputime/time*100,'% )')
    print('Stats: IO Busy ',iotime,' (',iotime/time*100,'% )')
if __name__=='__main__':
    go()  

四、实验结果

管理实验结果如下图所示,其中Time表示时间片,PID0=PID5表示6个进程,其中ready表示进程处于就绪态,run:cpu表示当前正在运行cpu指令,run:io表示正在进行io指令,此时会占用一个时间片的cpu,之后会继续进行三个时间片的阻塞,即waiting状态,done表示此进程指令已经全部执行完成。由于本实验是单处理机,所以CPU这一列表示此时间片是否占用cpu,包括run:io和run:cpu,1表示有cpu被占用,0表示没有cpu被占用。IOs表示此时间片被占用io数量,为0表示无waiting,由于阻塞可以多个进程同时进行,所以其他数字即表示当前时间片waiting总数。Total Time表示总时间片个数,图中表示为执行本程序共用29个时间片,CPU Busy表示占用cpu的时间,图中表示cpu占用24个时间片,后面括号内数字为占用cpu时间与运行程序总时间的比,这里为24/29所得,IO Busy表示占用io的总时间,这里27表示有27个时间片使用了io,后面的百分比是使用io时间与总时间的比,这里是27/29。

在这里插入图片描述
五、小结
这里我模拟了操作系统对进程的管理,实现了进程之间的切换,我们应该对操作系统的进程管理有一定的了解,了解进程是如何调度的,如何执行的。这里通过readyqueue、runningProcess、waitingqueue三个队列来管理进程,通过出队入队等操作将进程作为节点在不同队列上切换,并根据不同进程当前指令判断,这样就实现了进程状态的转换,需要要理解操作系统后台对进程是如何进行调度的,操作系统会按照一定逻辑来完成调度,在这里我按照自己的理解来设计,实现了多进程的并发执行,这就需要一定的调度机制,初始时,所有进程均放入就绪队列,然后会从就绪队列取出第一个进程放入执行队列,判断此进程第一个指令是哪种,是cpu指令则执行run:cpu,此时cpu将处于忙碌状态,且由于是单cpu,同一时刻只能有一个进程占用cpu,若是io则执行run:io,此时也会占用cpu,在之后需要将其放入阻塞队列,执行三次waiting,才可以被放回就绪队列,然后还会从就绪队列取进程,如此往复,直到redyqueue和waitingqueue全为空,即所有进程的所有指令都进行完毕,程序结束。

(如有问题,欢迎留言)

  • 4
    点赞
  • 49
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值