Python实现操作系统内存分配最佳算法
from typing import List
import random, json, time
# 进程类
class multi_class:
def __init__(self, id, name, size, state, memory_id=-1):
self.id = id
self.name = name
self.size = size
self.state = state
self.memory_id = memory_id
def __str__(self):
return "{" + f'id:"{self.id}", name:"{self.name}", size:"{self.size}", state:"{self.state}", memory_id:"{self.memory_id}"' + "}"
__repr__ = __str__
# 内存类
class memory_class:
def __init__(self, id=-1, start_mac=-1, size=-1, state=-1, multi_id=-1):
self.id = id
self.start_mac = start_mac
self.size = size
self.state = state
self.multi_id = multi_id
def __str__(self):
return "{" + f'id:"{self.id}", start_mac:"{self.start_mac}", size:"{self.size}", state:"{self.state}", multi_id:"{self.multi_id}"' + "}"
__repr__ = __str__
# 生成列表id
def get_max_id(ls: List):
if not ls:
return 1
return max(ls, key=lambda x: x.id).id + 1
# 根据空间对列表进行排序
def sort_list(ls: List):
return sorted(ls, key=lambda x: int(x.size))
# 根据id获取分配的内存
def get_memory_by_id(ls: List, id):
for l in ls:
if l.id == id:
return l
# 回收状态
state_recycle = {
1: "三分区合并",
2: "向下合并",
3: "向上合并",
4: "未合并"
}
# 内存忙碌表
busy_memory_list = []
# 进程列表
multi_list = []
# 内存空闲表
free_memory_list = []
# 最小分割内存
min_split = 5
# 分配内存方法
def memory_split(multi):
global free_memory_list, busy_memory_list
N = len(free_memory_list)
# 循环空闲分区表
for i in range(N):
# 空闲分区大小能装下当前的应用程序
if free_memory_list[i].size >= multi.size:
# 空闲分区
memory = free_memory_list[i]
# 切割完的分区小于最小分区
if (memory.size - multi.size) < min_split:
memory.state = 1
memory.id = get_max_id(busy_memory_list)
memory.multi_id = multi.id
multi.memory_id = memory.id
busy_memory_list.append(memory)
free_memory_list.remove(i)
# 切割完的分区大于等于最小分区
else:
free_memory_list.append(memory_class(
id=get_max_id(free_memory_list),
state=0,
start_mac=memory.start_mac + multi.size,
size=memory.size - multi.size
))
memory.state = 1
memory.id = get_max_id(busy_memory_list)
memory.size = multi.size
memory.multi_id = multi.id
multi.memory_id = memory.id
multi.state = 1
busy_memory_list.append(memory)
free_memory_list.remove(free_memory_list[i])
free_memory_list = sort_list(free_memory_list)
busy_memory_list = sort_list(busy_memory_list)
return True
return False
# 回收内存方法
def memory_recycle(multi):
global free_memory_list, busy_memory_list
# 从内存忙碌表中获取内存对象
busy_m = get_memory_by_id(busy_memory_list, multi.memory_id)
# 检索能不能将分区合并
for free_m in free_memory_list:
# 空闲分区的起始地址 == 忙碌地址 + 忙碌的大小 向下合并 忙碌地址小
if free_m.start_mac == busy_m.start_mac + busy_m.size:
# 空闲地址 == 忙碌地址 + 忙碌的大小 向下合并 空闲地址小
for m in free_memory_list:
if m.start_mac + m.size == busy_m.start_mac:
# 合并三个分区大小
m.size += free_m.size + busy_m.size
# 从忙碌表中移除
busy_memory_list.remove(busy_m)
# 将第一个空闲 从表中移除
free_memory_list.remove(free_m)
multi.memory_id = -1
multi.state = 0
free_memory_list = sort_list(free_memory_list)
# 三个分区合并 返回状态码 1
return 1
# 起始地址设置为忙碌地址
free_m.start_mac = busy_m.start_mac
# 合并两个分区
free_m.size = free_m.size + busy_m.size
# 从忙碌表中移除
busy_memory_list.remove(busy_m)
# 将进程的内存id设置为 -1 代表空
multi.memory_id = -1
# 将进程状态改为 未运行 0
multi.state = 0
free_memory_list = sort_list(free_memory_list)
# 向下合并返回状态码 2
return 2
# 空闲地址+空闲大小 == 忙碌地址 向上合并 空闲地址小
elif free_m.start_mac + free_m.size == busy_m.start_mac:
# 空闲地址 == 忙碌地址 + 忙碌的大小 向下合并 忙碌地址小
for m in free_memory_list:
if m.start_mac == busy_m.start_mac + busy_m.size:
# 起始地址设置为第一个空闲地址
m.start_mac = free_m.start_mac
# 合并三个分区大小
m.size += free_m.size + busy_m.size
busy_memory_list.remove(busy_m)
free_memory_list.remove(free_m)
multi.memory_id = -1
multi.state = 0
free_memory_list = sort_list(free_memory_list)
# 三个分区合并返回状态码 1
return 1
free_m.size = free_m.size + busy_m.size
busy_memory_list.remove(busy_m)
multi.memory_id = -1
multi.state = 0
# 向上合并返回状态码 3
free_memory_list = sort_list(free_memory_list)
return 3
# 没有合并的分区
free_memory_list.append(memory_class(
id=get_max_id(free_memory_list),
start_mac=busy_m.start_mac,
size=busy_m.size,
state=0
))
busy_memory_list.remove(busy_m)
multi.memory_id = -1
multi.state = 0
free_memory_list = sort_list(free_memory_list)
# 没有合并返回状态码 4
return 4
# 输出
def print_list():
width = 12
width_title = 10
print(("-" * 20) + " 内存空闲表 " + ("-" * 20))
print("内存编号".ljust(width_title), "起始地址".ljust(width_title), "大小".ljust(width_title))
for meory in free_memory_list:
print(str(meory.id).ljust(width), str(meory.start_mac).ljust(width),
str(meory.size).ljust(width))
print("")
print(("-" * 20) + " 内存忙碌表 " + ("-" * 20))
print("内存编号".ljust(width_title), "起始地址".ljust(width_title), "大小".ljust(width_title),
"进程名称".ljust(width_title))
for meory in busy_memory_list:
m = get_memory_by_id(multi_list, meory.multi_id)
print(str(meory.id).ljust(width), str(meory.start_mac).ljust(width),
str(meory.size).ljust(width), str(m.name).ljust(width))
print("")
# 调用分配内存方法
def run_split(multi):
# 当前进程已执行
if multi == 1:
return
if not memory_split(multi):
print(f"进程【{multi.name}】调用失败,内存不足")
else:
print(f"进程【{multi.name}】调用成功。")
print_list()
# 调用内存回收方法
def run_recycle(multi):
global state_recycle
# 当前进程未执行
if multi.state == 0:
return
state = memory_recycle(multi)
print(f"进程【{multi.name}】关闭成功,合并状态:{state_recycle[state]}")
print_list()
if __name__ == '__main__':
# 读取初始化数据
with open("config.json","r",encoding="utf-8") as f:
js = f.read()
js = json.loads(js)
# 初始化进程
for m in js["multi_list"]:
multi_list.append(multi_class(
id=get_max_id(multi_list),
name=m["name"],
size=int(m["size"]),
state=int(m["state"])
))
# 初始化空闲分区表
for m in js["free_memory_list"]:
free_memory_list.append(memory_class(
id=get_max_id(free_memory_list),
start_mac=int(m["start_mac"]),
size=int(m["size"]),
state=int(m["state"])
))
# 初始化忙碌分区表
for m in js["busy_memory_list"]:
free_memory_list.append(memory_class(
id=get_max_id(free_memory_list),
start_mac=int(m["start_mac"]),
size=int(m["size"]),
state=int(m["state"])
))
# 随机执行集合
ls = []
# 根据进程数量生成随机执行集合
for i in range(len(multi_list)):
ls.append("1_" + str(i))
ls.append("2_" + str(i))
# 随机执行开始进程和回收进程
for m in random.sample(ls, len(ls)):
n = m.split("_")
if n[0] == "1":
run_split(multi_list[int(n[1])])
elif n[0] == "2":
run_recycle(multi_list[int(n[1])])
time.sleep(random.randint(1, 4))
下面是config.json文件
{
“multi_list”: [
{
“name”: “完蛋!我被美女包围了”,
“size”: 50,
“state”: 0
},
{
“name”: “原神”,
“size”: 83,
“state”: 0
},
{
“name”: “CS2”,
“size”: 2,
“state”: 0
},
{
“name”: “英雄联盟”,
“size”: 22,
“state”: 0
},
{
“name”: “极品飞车”,
“size”: 33,
“state”: 0
}
],
“free_memory_list”: [
{
“start_mac”:0,
“size”:1000,
“state”:0
}
],
“busy_memory_list”:[]
}