实现效果
流程图
代码讲解
1.pcb结构体
# pcb结构体
# pcb结构体
class pcb:
# 基本属性
p_id=0 #进程id,系统自己赋值
p_name="" #进程name
p_state="" #没有用到
p_runtime=0 #进程执行完所需的时间片
p_require=0 #阻塞进程所依赖的进程id
def __init__(self,id,name,state,runtime,require):
self.p_id=id
self.p_name=name
self.p_state=state
self.p_runtime=runtime
self.p_require=require
2.全局变量
# 全局变量
creat=[] #创建序列,因为对创建进程没有内存的限制所以也没用到。
ready=[] #就绪队列
block=[] #阻塞队列
run=[] #运行队列,一个时间只有一个进程在里面
exit=[] #完成队列,运行完成的队列
num_i=7 #因为我提前自动创建了5个进程,所以num从7开始
window = tk.Tk() #可视化
3.创建进程模块
def creat_fuc():
global num_i
id=num_i+1
num_i=num_i+1
name=input("请输入进程的名字:")
runtime=int(input("请输入进程需要的时间片:"))
# 设置require 值
if(len(ready)==0):
require=0
else:
random_num=random.randint(1,10)
if(random_num<=len(ready)):
require=ready[random_num-1].p_id
else:
require=0
# 通过require设置state
if(require==0):
state="ready"
else:
state="block"
# 添加进相应的ready/block队列
new_code=pcb(id,name,state,runtime,require)
if(state=="ready"):
ready.append(new_code)
else:
block.append(new_code)
#如果run为0
if(len(run)==0):
run.append(ready[0])
del ready[0]
4.运行进程模块
def run_fuc():
run[0].p_runtime = run[0].p_runtime-1
# 进程运行完成
if(run[0].p_runtime==0):
#添加到完成队列中并且把新的进程加入到run中
exit.append(run[0])
#查看block队列中有可以转移到ready中的
delnum=[]
for i in range (len(block)):
if(run[0].p_id==block[i].p_require):
block[i].p_require=0
ready.append(block[i])
delnum.append(i)
#必须倒序
delnum.reverse()
for i in range (len(delnum)):
del block[delnum[i]]
#再删去run0,换一个新的
del run[0]
#如果ready为0
if(len(ready)==0):
print("全部进程执行完毕")
else:
run.append(ready[0])
del ready[0]
#进程没有完成
else:
ready.append(run[0])
del run[0]
#将ready中的第一个加到run中
run.append(ready[0])
del ready[0]
5. 阻塞进程模块
def block_fuc():
run[0].p_runtime = run[0].p_runtime-1
# 进程运行完成
if(run[0].p_runtime==0):
#添加到完成队列中
exit.append(run[0])
#查看block队列中有可以转移到ready中的
delnum=[]
for i in range (len(block)):
if(run[0].p_id==block[i].p_require):
block[i].p_require=0
ready.append(block[i])
delnum.append(i)
#必须倒序
delnum.reverse()
for i in range (len(delnum)):
del block[delnum[i]]
#再删去run0,换一个新的
del run[0]
#如果ready为0
if(len(ready)==0):
print("全部进程执行完毕")
else:
run.append(ready[0])
del ready[0]
#进程没有完成
else:
#且ready为空
if(len(ready)==0):
#没有任何操作
pass
else:
random_num=random.randint(1,len(ready))
run[0].p_require = ready[random_num-1].p_id
block.append(run[0])
del run[0]
#将ready中的第一个加到run中
run.append(ready[0])
del ready[0]
6.停止模块
def stop():
quit()
7.提前创建7个进程
new_code=pcb(1,"name","state",1,0)
run.append(new_code)
new_code=pcb(2,"name","state",2,0)
ready.append(new_code)
new_code=pcb(3,"name","state",3,0)
ready.append(new_code)
new_code=pcb(4,"name","state",4,0)
ready.append(new_code)
new_code=pcb(5,"name","state",2,2)
block.append(new_code)
new_code=pcb(6,"name","state",3,3)
block.append(new_code)
new_code=pcb(7,"name","state",4,4)
block.append(new_code)
#提前添加7个进程,运行队列一个,就绪队列3个,阻塞队列3个。
8.主函数
# main()
# 调用mainloop()显示主窗口
def main():
window.title('进程状态转换实验')
window.geometry('600x300')
button_stop=tk.Button(window,text='停止',width=20, height=5,command=stop)
button_creat=tk.Button(window,text='创建',width=20, height=5,command=creat_fuc)
button_run=tk.Button(window,text='运行',width=20, height=5,command=run_fuc)
button_block=tk.Button(window,text='阻塞',width=20, height=5,command=block_fuc)
text_exit = tk.Text(window, width=50, height=30, undo=True, autoseparators=False)
text_block = tk.Text(window, width=50, height=30, undo=True, autoseparators=False)
text_ready = tk.Text(window, width=50, height=30, undo=True, autoseparators=False)
text_run = tk.Text(window, width=50, height=30, undo=True, autoseparators=False)
设置button按钮和text文本框
text_exit.grid(row=0,column=2)
text_block.grid(row=1,column=1)
text_ready.grid(row=1,column=2)
text_run.grid(row=1,column=3)
button_stop.grid(row=3,column=1)
button_creat.grid(row=3,column=2)
button_run.grid(row=3,column=3)
button_block.grid(row=3,column=4)
放置button和text
while(1):
run_text=""
for i in range(len(run)):
run_text="运行队列:"+str(run[i].p_id)+" 所需时间片:"+str(run[i].p_runtime)
block_text=""
for i in range (len(block)):
block_text=block_text + "阻塞队列:" + str(block[i].p_id) + " 等待进程:" + str(block[i].p_require) +"\n"
ready_text=""
for i in range (len(ready)):
ready_text=ready_text + "就绪队列:" + str(ready[i].p_id) + " 所需时间片:" + str(ready[i].p_runtime) +"\n"
exit_text=""
for i in range (len(exit)):
exit_text=exit_text + "完成队列:" + str(exit[i].p_id) +"\n"
text_run.delete(0.0,tk.END)
text_run.insert(tk.INSERT,run_text)
text_block.delete(0.0,tk.END)
text_block.insert(tk.INSERT,block_text)
text_ready.delete(0.0,tk.END)
text_ready.insert(tk.INSERT,ready_text)
text_exit.delete(0.0,tk.END)
text_exit.insert(tk.INSERT,exit_text)
window.update()
time.sleep(0.2)
设置循环不断更新text文本更新原理为:
text_run.delete(0.0,tk.END)#先删除text文本框中的内容
text_run.insert(tk.INSERT,run_text)
#再将更新后的run_text内容insert进入文本框
window.update() #刷新界面
time.sleep(0.2) #每0.2s刷新一次
三、操作流程
main() #调用main函数后界面会弹出
注意:点击创建后需要回到控制台输入内容。然后就可以在界面看到新创建的进程。