操作系统实验-进程控制(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
    评论
首先,你需要了解操作系统进程调度的一些基本概念。进程调度是操作系统内核的重要组成部分,它负责在多个进程之间分配 CPU 时间。操作系统会根据一定的策略来选择下一个要执行的进程。 在 Python 中,你可以使用 multiprocessing 模块来创建进程。该模块提供了 Process 类,你可以通过该类创建新的进程。下面是一个简单的示例: ```python import multiprocessing def my_process(): print("This is my process.") if __name__ == '__main__': p = multiprocessing.Process(target=my_process) p.start() p.join() ``` 在这个示例中,我们定义了一个名为 `my_process` 的函数,它会在一个新进程中运行。在 `__name__ == '__main__'` 的条件下,我们创建了一个新的进程 `p` 并启动它。然后我们使用 `p.join()` 等待该进程完成。 接下来,你可以使用 Python 的队列模块 `queue` 来模拟操作系统中的进程队列。该模块提供了 Queue 类,你可以使用它来实现一个简单的进程调度器。下面是一个示例: ```python import multiprocessing import queue def my_process(q): while True: try: task = q.get(block=False) print("Processing task:", task) except queue.Empty: break if __name__ == '__main__': q = multiprocessing.Queue() for i in range(10): q.put(i) processes = [] for i in range(4): p = multiprocessing.Process(target=my_process, args=(q,)) p.start() processes.append(p) for p in processes: p.join() ``` 在这个示例中,我们创建了一个名为 `q` 的队列,并将 10 个任务放入该队列中。然后我们创建了 4 个进程,并每个进程都调用 `my_process` 函数来处理队列中的任务。 在 `my_process` 函数中,我们使用一个无限循环来从队列中取出任务,并进行处理。当队列为空时,我们跳出循环,这样该进程就会自动退出。 最后,我们使用 `p.join()` 等待所有进程完成。这样我们就实现了一个简单的进程调度器。
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值