要求:
- 定义分页的地址结构和页表结构。
- 对进程的逻辑地址空间、页表起址、给定的逻辑地址进行初始化。
- 实现从逻辑地址到物理地址的变换。
- 实现“主存空间的共享和保护”功能。
- 实现“主存扩充”虚拟功能。
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()