本文是博主之前做的操作系统实验,现在将完整代码和效果图免费放在下面,供大家参考,如果觉得有用,希望大家可以三连+关注支持!!!!!!
实验目的
设计编写OS进程与内存管理模拟程序,模拟OS进程的创建、阻塞、唤醒、撤销等进程控制以及OS内存管理方法和过程,加深操作系统进程控制原语主要任务和过程的理解,加深操作系统内存分配的基本策略,加深操作系统以进程为核心的完整架构的理解。提高综合性实验的分析、设计及编程实现能力。
实验内容
设计一个OS进程与内存管理模拟程序,要求:
程序运行后提供一个交互界面或窗口,允许用户输入以下命令并可以滴对命令进行解释执行,
creatproc:提交作业命令,要求用户提供作业估计运行时长和内存大小需求。该命令的解释执行过程为对该作业创建对应的进程,完成PCB建立、存储空间分配等工作。(既执行OS的创建进程原语)
killproc 进程号:终止进程命令。该命令的解释执行过程为对进程进行撤销,回收存储空间和PCB。
iostrartproc 进程号:阻塞进程命令。该命令的解释执行过程为对处于运行状态的进程进行阻塞操作,进程状态转为阻塞状态。
iofinishproc 进程号:唤醒进程命令。该命令的解释执行过程为对处于阻塞状态的进程进行唤醒操作,进程状态转为就绪状态。
psproc:显示所有进程状态命令。该命令的解释执行过程为显示出所有进程的状态信息,主要包括进程id,进程状态,存储空间地址。
mem:显示内存空间使用情况信息。该命令的解释执行过程为显示内存空间的占用和空闲情况。
设计思路提示:内存空间可用数组模拟,主要原语模拟实现,包括创建进程,终止进程,阻塞进程,唤醒进程,进程调度等原语。进程调度算法可选择 FCFS、RR、SJF中任意一种。内存分配可选择可变分区策略或页式内存分配方案中任意一种。
程序设计语言不限。
效果展示
运行程序
依次创建三个进程,运行时间分别为5、4、3,内存均为100
查看此时的进程状态和内存分配情况:
开始调度由于使用的是SJF调度算法,所有会先调度进程3:
每点一次调度,正在运行的进程的剩余时间减一:
下面测试内存不够的情况下,创建内存会发生什么,创建一个内存大小为800的进程如图报错
下面测试阻塞进程和唤醒进程的功能,要先阻塞进程3,然后调度,让进程2运行,然后阻塞进程2,然后调度,让进程1运行,然后阻塞:
依次唤醒三个进程:
测试终止进程功能,将进程2终止:
内存情况
然后检验内存分配的首次适应算法的功能,即创建一个进程,内存大小为101
最后一直点调度,直到进程全部结束
完整代码
from tkinter import *
import random
cnt = 0
# 定义进程类
class Process:
def __init__(self, pid, runtime, memsize):
self.pid = pid
self.runtime = runtime
self.memsize = memsize
self.status = "Ready"
self.memstart = -1
# 定义内存类
class Memory:
def __init__(self, size):
self.size = size
self.memory = [0] * size
self.free_blocks = [(0, size-1)]
def allocate(self, size, pid):
for i, block in enumerate(self.free_blocks):
if block[1]-block[0]+1 >= size:
start = block[0]
end = start + size - 1
self.free_blocks.pop(i)
if block[1] != end:
self.free_blocks.insert(i, (end+1, block[1]))
if block[0] != start:
self.free_blocks.insert(i, (block[0], start-1))
for j in range(start, end+1):
self.memory[j] = pid
return start
return -1
def free(self, start, pid):
end = start + pid.memsize - 1
for i in range(start, end+1):
self.memory[i] = 0
self.free_blocks.append((start, end))
self.free_blocks.sort()
# 定义进程列表和内存对象
process_list = []
memory = Memory(1024)
# 创建进程命令,需要用户输入作业运行时间和内存需求
def create_proc():
time = entry1.get()
mem = entry2.get()
global cnt
cnt = cnt + 1
pid = cnt
runtime = int(time)
memsize = int(mem)
process = Process(pid, runtime, memsize)
memstart = memory.allocate(memsize, pid)
if memstart == -1:
status_text.insert(END,"Memory allocation failed.\n")
return
process.memstart = memstart
process_list.append(process)
status_text.insert(END,"Process created with PID {}.\n".format(pid))
# 终止进程命令,需要用户输入要终止的进程ID
def kill_proc1():
pid = entry1.get()
pid = int(pid)
for i, process in enumerate(process_list):
if process.pid == pid:
process.status = "Terminated"
memory.free(process.memstart, process)
del process_list[i]
status_text.insert(END,"Process {} terminated.\n".format(pid))
return
status_text.insert(END,"Process {} not found.\n".format(pid))
show_proc()
# 终止进程命令,自动
def kill_proc2(pid):
for i, process in enumerate(process_list):
if process.pid == pid:
process.status = "Terminated"
memory.free(process.memstart, process)
del process_list[i]
status_text.insert(END,"Process {} terminated.\n".format(pid))
return
status_text.insert(END,"Process {} not found.\n".format(pid))
show_proc()
# 阻塞进程命令,需要用户输入要阻塞的进程ID
def block_proc():
pid = entry1.get()
pid = int(pid)
for process in process_list:
if process.pid == pid:
if process.status == "Running":
process.status = "Blocked"
status_text.insert(END,"Process {} blocked.\n".format(pid))
return
else:
status_text.insert(END,"Process {} not running.\n".format(pid))
return
status_text.insert(END,"Process {} not found.\n".format(pid))
# 唤醒进程命令,需要用户输入要唤醒的进程ID
def unblock_proc():
pid = entry1.get()
pid = int(pid)
for process in process_list:
if process.pid == pid:
if process.status == "Blocked":
process.status = "Ready"
status_text.insert(END,"Process {} unblocked.\n".format(pid))
return
else:
status_text.insert(END,"Process {} not blocked.\n".format(pid))
return
status_text.insert(END,"Process {} not found.\n".format(pid))
# 执行调度命令,根据短时间优先非抢占式算法选择下一个要运行的进程
def schedule():
shortest_process = None
shortest_runtime = sys.maxsize
for process in process_list:
if process.status == "Running":
process.runtime -= 1
if process.runtime == 0:
kill_proc2(process.pid)
return
if shortest_process is None or process.runtime < shortest_runtime:
shortest_process = process
shortest_runtime = process.runtime
if shortest_process is None:
for process in process_list:
if process.status == "Ready":
if shortest_process is None or process.runtime < shortest_runtime:
shortest_process = process
shortest_runtime = process.runtime
if shortest_process is not None:
shortest_process.status = "Running"
status_text.insert(END,"Process {} running.\n".format(shortest_process.pid))
else:
status_text.insert(END,"Process {} running.\n".format(shortest_process.pid))
show_proc()
# 显示进程状态命令,将进程列表和它们的状态显示在屏幕上
def show_proc():
# 清空进程显示区域
proc_list.delete(0, END)
# 遍历进程列表,将每一个进程的信息添加到进程显示区域中
for proc in process_list:
proc_info = f"进程号:{proc.pid},状态:{proc.status},剩余时间:{proc.runtime },内存大小:{proc.memsize},地址:{proc.memstart}"
proc_list.insert(END, proc_info)
# 显示内存分配情况命令,将内存分配情况显示在屏幕上
# 定义内存显示函数,将数据写入内存文本框
def show_mem():
# 清空进程显示区域
memory_text.delete(1.0, END)
i = 0
while i < memory.size:
if memory.memory[i] == 0:
block_start = i
block_size = 0
while i < memory.size and memory.memory[i] == 0:
block_size += 1
i += 1
memory_text.insert(END, "Free block: Start = {}, Size = {}\n".format(block_start, block_size))
else:
pid = memory.memory[i]
block_start = i
block_size = 0
while i < memory.size and memory.memory[i] == pid:
block_size += 1
i += 1
memory_text.insert(END, "Used block: PID = {}, Start = {}, Size = {}\n".format(pid, block_start, block_size))
# 创建主窗口
root = Tk()
root.title("OS进程与内存管理模拟程序")
top_frame = Frame(root)
top_frame.pack(side=TOP)
# 添加进程运行时间输入框和标签
run_time_lbl = Label(top_frame, text="进程运行时间/进程号:")
run_time_lbl.pack(side=LEFT)
entry1 = Entry(top_frame)
entry1.pack(side=LEFT)
# 添加进程内存大小输入框和标签
mem_size_lbl = Label(top_frame, text="进程内存大小:")
mem_size_lbl.pack(side=LEFT)
entry2 = Entry(top_frame)
entry2.pack(side=LEFT)
button1 = Button(top_frame, text="创建进程", command=create_proc)
button1.pack(side=LEFT)
button2 = Button(top_frame, text="终止进程", command=kill_proc1)
button2.pack(side=LEFT)
button3 = Button(top_frame, text="阻塞进程", command=block_proc)
button3.pack(side=LEFT)
button4 = Button(top_frame, text="唤醒进程", command=unblock_proc)
button4.pack(side=LEFT)
button5 = Button(top_frame, text="调度", command=schedule)
button5.pack(side=LEFT)
button6 = Button(top_frame, text="显示进程状态", command=show_proc)
button6.pack(side=LEFT)
button7 = Button(top_frame, text="显示内存分配情况", command=show_mem)
button7.pack(side=LEFT)
# 添加进程状态显示区域,并将它放在窗口的左侧
left_frame = Frame(root, width=300, height=400)
left_frame.pack(side=LEFT)
# 添加垂直和水平滚动条
y_scrollbar = Scrollbar(left_frame)
y_scrollbar.pack(side=RIGHT, fill=Y)
x_scrollbar = Scrollbar(left_frame, orient=HORIZONTAL)
x_scrollbar.pack(side=BOTTOM, fill=X)
# 添加进程列表框,并使其具有垂直和水平滚动条控制的能力
proc_list = Listbox(left_frame, yscrollcommand=y_scrollbar.set, xscrollcommand=x_scrollbar.set, width=40, height=20)
proc_list.pack(side=LEFT, fill=BOTH)
# 设置滚动条控制
y_scrollbar.config(command=proc_list.yview)
x_scrollbar.config(command=proc_list.xview)
# 将进程列表框和滚动条添加到左侧框架中
# 添加状态信息显示区域,并将其放在进程列表和内存分配情况显示之间
status_frame = Frame(root)
status_frame.pack(side=LEFT)
status_label = Label(status_frame, text="状态信息")
status_label.pack()
status_text = Text(status_frame, width=40, height=20)
status_text.pack(side=LEFT)
# 添加垂直滚动条并将其与状态文本框配对
scrollbar = Scrollbar(status_frame, orient=VERTICAL, command=status_text.yview)
scrollbar.pack(side=RIGHT, fill=Y)
status_text.configure(yscrollcommand=scrollbar.set)
# 添加内存分配情况显示区域,并将它放在窗口的右侧
right_frame = Frame(root)
right_frame.pack(side=RIGHT)
memory_label = Label(right_frame, text="内存分配情况")
memory_label.pack()
memory_text = Text(right_frame, bg="white", width=40, height=20)
memory_text.pack()
# 进入主循环
root.mainloop()