要求:
- 定义分页的地址结构和页表结构。
- 对进程的逻辑地址空间、页表起址、给定的逻辑地址进行初始化。
- 实现从逻辑地址到物理地址的变换。
- 实现“主存空间的共享和保护”功能。
- 实现“主存扩充”虚拟功能。
import random
import sys
'''
nei:主存容量
wai:外存容量
b:页面大小
c:页面数
d:页表
k:逻辑地址
f:物理地址
occupy:已用物理块
'''
def aaa(nei, wai, b, c):
# 已占内存
occupy1 = []
hh1 = []
for i in range((nei // (b * 2) - 4)):
hh = random.randint(0, nei // b)
while hh in hh1:
hh = random.randint(0, nei // b)
hh1.append(hh)
occupy1.append(hh)
# 占用大量内存
occupy3 = []
hh3 = []
for i in range((nei // b - 4)):
hh = random.randint(0, nei // b)
while hh in hh3:
hh = random.randint(0, nei // b)
hh3.append(hh)
occupy3.append(hh)
# 已占外存
occupy2 = []
hh2 = []
for i in range(wai // (3 * b)):
hh = random.randint(0, wai // b)
while hh in hh2:
hh = random.randint(0, wai // b)
hh2.append(hh)
occupy2.append(hh)
hhh = eval(input("请选择需不需要内存扩充: 1 需要 2 不需要: "))
# 设置页表并进行初始化
d = {} # 页表,包含页号,物理块号,状态位,访问字段A,修改位M,外存地址
d1 = [] # 用来存放已有内存物理块号
d2 = [] # 用来存放已有外存物理块号
dd = [] # 用来存放页表中除页号的所有信息
if hhh == 2:
ff = (nei // b) - len(occupy1)
if c <= ff:
for i in range(c):
j1 = random.randint(0, nei // b)
j2 = random.randint(0, wai // b)
while j1 in d1 or j1 in occupy1:
j1 = random.randint(0, nei // b)
while j2 in d2 or j2 in occupy2:
j2 = random.randint(0, nei // b)
d1.append(j1)
d2.append(j2)
occupy2.append(j2)
dd.append(j1) # 将内存物理块号放入dd
dd += [0, 0, 0] # 设置状态位P为0,访问字段A为0,修改位M为0
dd.append(j2) # 将外存物理块号放入dd
dd.append(0) # 共享状态,1共享
d[i] = dd
dd = []
for i in range(c // 2): # 将一半页表放入内存
d[i][1] = 1
occupy1.append(d[i][0])
occupy2.remove(d[i][4])
for i in range(c // 2, (c // 2) + 2):
d[i][3] = 1
for i in range(c // 2):
x = random.randint(0, c-1)
d[x][5] = 1
print("页表为: ")
print("页号 物理块号 状态位 访问字段 修改位 外存地址 共享状态")
for i in range(c):
print(" {0:>0} {1:>4} {2:>5} {3:>7}{4:>9}{5:>12}{6:>13}".format(i, d[i][0], d[i][1], d[i][2], d[i][3], d[i][4], d[i][5]))
# 设置逻辑地址并将其转化成物理地址
k = input("请输入逻辑地址(可十进制输入或十六进制输入):")
if "0" <= k[-1] <= "9" or k[-1] == "H" or k[-1] == "h":
n = []
e = 0
if k[-1] == "H" or k[-1] == "h":
j = {"a": 10, "A": 10, "b": 11, "B": 11, "c": 12, "C": 12, "d": 13, "D": 13, "e": 14, "E": 14, "f": 15, "F": 15}
for i in range(len(k)-1):
if k[i] in j.keys():
n.append(j[k[i]])
else:
n.append(eval(k[i][0]))
for i in range(len(n)):
e += n[i] * (16 ** (len(n)-1-i))
else:
e = eval(k)
page = e // b # 页号
offest = e % b # 页内偏移量
if page >= c:
print("产生越界中断: ")
sys.exit() # 终止程序
if d[page][1] == 0: # 判断该页在不在内存,1在,0不在
print("缺的页: ", d[page])
if d[page][0: 5] == [0, 0, 0, 0, 0] or d[page][0: 5] == [0, 0, 0, 1, 0]: # 判断内存满否,此时内存满
print("内存已满,选择一页置换出!")
x = random.randint(0, len(occupy1)-1) # 内存满时选择一页换出
if d[page][3] == 1: # 判断该页是否修改,0为否,1为是
print("该页已被修改,将重新写入外存")
j2 = random.randint(0, wai // b)
while j2 in d2 or j2 in occupy2:
j2 = random.randint(0, nei // b)
d[page][4] = j2
d[page][3] = 0
print("将该页写入外存后为:{0}:{1}".format(page, d[page]))
d[page][0] = occupy1[x] # 设置缺页的物理块为从外存置换出的
print("置换的物理地址为: ", occupy1[x])
d[page][1] = 1 # 将该页从外存换入内存
physical = d[page][0] # 对应的物理块号
f = hex(physical * b + offest) # 物理地址
f = list(f)
del f[:2]
f.append("h")
f = "".join(f)
print("逻辑地址页号为{},页内偏移为{}".format(page, offest))
print("{}对应的物理地址为:{}".format(k, f))
else:
physical = d[page][0] # 对应的物理块号
f = hex(physical * b + offest) # 物理地址
f = list(f)
del f[:2]
f.append("h")
f = "".join(f)
print("逻辑地址页号为{},页内偏移为{}".format(page, offest))
print("{}对应的物理地址为:{}".format(k, f))
else:
print("输入错误!")
sys.exit()
elif hhh == 1:
ff = (nei // b) - len(occupy3)
if c <= ff:
for i in range(c):
j1 = random.randint(0, nei // b)
j2 = random.randint(0, wai // b)
while j1 in d1 or j1 in occupy3:
j1 = random.randint(0, nei // b)
while j2 in d2 or j2 in occupy2:
j2 = random.randint(0, nei // b)
d1.append(j1)
d2.append(j2)
occupy2.append(j2)
dd.append(j1) # 将内存物理块号放入dd
dd += [0, 0, 0] # 设置状态位P为0,访问字段A为0,修改位M为0
dd.append(j2) # 将外存物理块号放入dd
dd.append(0) # 共享状态,1共享
d[i] = dd
dd = []
for i in range(c // 2): # 将一半页表放入内存
d[i][1] = 1
occupy3.append(d[i][0])
occupy2.remove(d[i][4])
for i in range(c // 2, (c // 2) + 2):
d[i][3] = 1
else:
for i in range(ff):
j1 = random.randint(0, nei // b)
j2 = random.randint(0, wai // b)
while j1 in d1 or j1 in occupy3:
j1 = random.randint(0, nei // b)
while j2 in d2 or j2 in occupy2:
j2 = random.randint(0, nei // b)
d1.append(j1)
d2.append(j2)
occupy2.append(j2)
dd.append(j1) # 将内存物理块号放入dd
dd += [0, 0, 0] # 设置状态位P为0,访问字段A为0,修改位M为0
dd.append(j2) # 将外存物理块号放入dd
dd.append(0)
d[i] = dd
dd = []
for i in range(ff, c): # 内存满时剩余的页表表示
d[i] = [0, 0, 0, 0, 0, 0]
d[c-2] = [0, 0, 0, 1, 0, 0] # 选一个页修改位置1
for i in range(ff // 2): # 将一半页表放入内存
d[i][1] = 1
occupy3.append(d[i][0])
occupy2.remove(d[i][4])
for i in range(ff // 2, (ff // 2) + 2):
d[i][3] = 1
d[1][5] = 1
print("页表为: ")
print("页号 物理块号 状态位 访问字段 修改位 外存地址 共享状态")
for i in range(c):
print(" {0:>0} {1:>4} {2:>5} {3:>7}{4:>9}{5:>12}{6:>13}".format(i, d[i][0], d[i][1], d[i][2], d[i][3], d[i][4], d[i][5]))
# 设置逻辑地址并将其转化成物理地址
k = input("请输入逻辑地址(可十进制输入或十六进制输入):")
if "0" <= k[-1] <= "9" or k[-1] == "H" or k[-1] == "h":
n = []
e = 0
if k[-1] == "H" or k[-1] == "h":
j = {"a": 10, "A": 10, "b": 11, "B": 11, "c": 12, "C": 12, "d": 13, "D": 13, "e": 14, "E": 14, "f": 15, "F": 15}
for i in range(len(k)-1):
if k[i] in j.keys():
n.append(j[k[i]])
else:
n.append(eval(k[i][0]))
for i in range(len(n)):
e += n[i] * (16 ** (len(n)-1-i))
else:
e = eval(k)
page = e // b # 页号
offest = e % b # 页内偏移量
if page >= c:
print("产生越界中断: ")
sys.exit() # 终止程序
if d[page][1] == 0: # 判断该页在不在内存,1在,0不在
print("缺的页: ", d[page])
if d[page][0: 5] == [0, 0, 0, 0, 0] or d[page][0: 5] == [0, 0, 0, 1, 0]: # 判断内存满否,此时内存满
print("内存已满,选择一页置换出!")
x = random.randint(0, len(occupy3)-1) # 内存满时选择一页换出
if d[page][3] == 1: # 判断该页是否修改,0为否,1为是
print("该页已被修改,将重新写入外存")
j2 = random.randint(0, wai // b)
while j2 in d2 or j2 in occupy2:
j2 = random.randint(0, nei // b)
d[page][4] = j2
d[page][3] = 0
print("将该页写入外存后为:{0}:{1}".format(page, d[page]))
d[page][0] = occupy3[x] # 设置缺页的物理块为从外存置换出的
print("置换的物理地址为: ", occupy3[x])
d[page][1] = 1 # 将该页从外存换入内存
physical = d[page][0] # 对应的物理块号
f = hex(physical * b + offest) # 物理地址
f = list(f)
del f[:2]
f.append("h")
f = "".join(f)
print("逻辑地址页号为{},页内偏移为{}".format(page, offest))
print("{}对应的物理地址为:{}".format(k, f))
else:
physical = d[page][0] # 对应的物理块号
f = hex(physical * b + offest) # 物理地址
f = list(f)
del f[:2]
f.append("h")
f = "".join(f)
print("逻辑地址页号为{},页内偏移为{}".format(page, offest))
print("{}对应的物理地址为:{}".format(k, f))
else:
print("输入错误!")
sys.exit()
else:
print("输入错误!")
sys.exit()
# 输出共享页表
gongxiang = {}
for i in range(c):
if d[i][5] == 1:
gongxiang[i] = d[i]
gongxiang[i].append(random.randint(1, 5))
print("共享的页表为:")
print("页号 物理块号 状态位 访问字段 修改位 外存地址 共享状态 共享进程计数")
for i in gongxiang.keys():
print(" {0:>0} {1:>4} {2:>5} {3:>7}{4:>9}{5:>11}{6:>12}{7:>13}".format(i, gongxiang[i][0], gongxiang[i][1], gongxiang[i][2], gongxiang[i][3], gongxiang[i][4], gongxiang[i][5], gongxiang[i][6]))
if page in gongxiang.keys():
gongxiang[page][6] += 1
print("此时的共享的页表为:")
print("页号 物理块号 状态位 访问字段 修改位 外存地址 共享状态 共享进程计数")
for i in gongxiang.keys():
print(" {0:>0} {1:>4} {2:>5} {3:>7}{4:>9}{5:>11}{6:>12}{7:>13}".format(i, gongxiang[i][0], gongxiang[i][1], gongxiang[i][2], gongxiang[i][3], gongxiang[i][4], gongxiang[i][5], gongxiang[i][6]))
print("随机结束几个进程")
aaa = list(gongxiang.keys())
for i in range(random.randint(1, 10)):
aaa1 = aaa[random.randint(0, len(aaa)-1)]
gongxiang[aaa1][6] -= 1
for i in aaa:
if gongxiang[i][6] <= 0:
gongxiang.pop(i)
print("此时的共享的页表为:")
print("页号 物理块号 状态位 访问字段 修改位 外存地址 共享状态 共享进程计数")
for i in gongxiang.keys():
print(" {0:>0} {1:>4} {2:>5} {3:>7}{4:>9}{5:>11}{6:>12}{7:>13}".format(i, gongxiang[i][0], gongxiang[i][1], gongxiang[i][2], gongxiang[i][3], gongxiang[i][4], gongxiang[i][5], gongxiang[i][6]))
# 定义主存容量
i = input("请输入主存容量(单位b,kb,mb): ")
if i[-2:] == "MB" or i[-2:] == "mb" or i[-2:] == "mB" or i[-2:] == "Mb":
nei = eval(i[:-2]) * (2 ** 20)
elif i[-2:] == "KB" or i[-2:] == "kb" or i[-2:] == "kB" or i[-2:] == "Kb":
nei = eval(i[:-2]) * (2 ** 10)
elif i[-1] == "B" or i[-1] == "b":
nei = eval(i[:-1])
elif i.isnumeric():
nei = eval(i)
else:
print("输入错误!")
sys.exit()
print("主存容量为:", nei, "b")
# 定义外存容量
i = input("请输入外存容量(单位b,kb,mb): ")
if i[-2:] == "MB" or i[-2:] == "mb" or i[-2:] == "mB" or i[-2:] == "Mb":
wai = eval(i[:-2]) * (2 ** 20)
elif i[-2:] == "KB" or i[-2:] == "kb" or i[-2:] == "kB" or i[-2:] == "Kb":
wai = eval(i[:-2]) * (2 ** 10)
elif i[-1] == "B" or i[-1] == "b":
wai = eval(i[:-1])
elif i.isnumeric():
wai = eval(i)
else:
print("输入错误!")
sys.exit()
print("外存容量为:", wai, "b")
# 定义页面大小
i = input("请输入页面大小(单位b,kb,mb): ")
if i[-2:] == "MB" or i[-2:] == "mb" or i[-2:] == "mB" or i[-2:] == "Mb":
b = eval(i[:-2]) * (2 ** 20)
elif i[-2:] == "KB" or i[-2:] == "kb" or i[-2:] == "kB" or i[-2:] == "Kb":
b = eval(i[:-2]) * (2 ** 10)
elif i[-1] == "B" or i[-1] == "b":
b = eval(i[:-1])
elif i.isnumeric():
b = eval(i)
else:
print("输入错误!")
sys.exit()
print("页面大小为:", b, "b")
# 定义页数
i = input("请输入页数(单位b,kb,mb): ")
if i[-2:] == "MB" or i[-2:] == "mb" or i[-2:] == "mB" or i[-2:] == "Mb":
c = eval(i[:-2]) * (2 ** 20)
elif i[-2:] == "KB" or i[-2:] == "kb" or i[-2:] == "kB" or i[-2:] == "Kb":
c = eval(i[:-2]) * (2 ** 10)
elif i[-1] == "B" or i[-1] == "b":
c = eval(i[:-1])
elif i.isnumeric():
c = eval(i)
else:
print("输入错误!")
sys.exit()
print("页面大小为:", c, "b")
hf = "y"
while hf == "y" or hf == "Y":
aaa(nei, wai, b, c)
hf = input("是否继续,是输入y,否n: ")
sys.exit()
|