问题:
编写一个程序,该程序能说明当有两个进程的简单情况下,使用局部页置换策略和全局页置换策略的差异。读者将会用到能生成一个基于统计模型的页面访问串的例程。这个模型有N个状态,从0到N-1,代表每个可能的页面访问,每个状态i相关的概率pi代表下一次访问仍指向同一页面的几率。否则,下一次页面访问将以等概率指向其他任何一个页面。
a)说明当N比较小时,页面访问串生成例程能运行正常。
b)对有一个进程和固定数量的页框的情况计算缺页中断率。解释这种结果为什么是正确的。
c)对有独立页面访问序列的两个进程,以及是b)中页框数两倍的页框,重复 b)。
d)用全局策略替换局部策略重复
c)。类似地,使用局部策略方法,比较每个进程缺页中断率。
代码实现(python):
import random
class PageReplacementSimulator:
# 页面置换模拟器,使用最近最少使用页面置换算法(LRU)
def __init__(self, num_pages, num_frames):
self.num_pages = num_pages
self.num_frames = num_frames # 页框
self.page_table1 = [] # 页表1
self.used1 = [] # 记录页表1各页面使用次数,数值越小则最近使用次数越少
self.page_table2 = [] # 页表2
self.used2 = [] # 记录页表2各页面使用次数,数值越小则最近使用次数越少
self.page_access_sequence = [] # 存储页面访问序列,记录命中信息
self.fault_num = 0 # 缺页次数,用来计算缺页率
def access_page(self, page):
#访问页
if page[0] == 1:
self.access_page1(page)
else:
self.access_page2(page)
def access_page1(self, page):
if page[1] in self.page_table1:
# 命中
idx = self.page_table1.index(page[1])
self.used1[idx] += 1#使用次数加1
self.page_access_sequence.append(('页表' + str(page[0]), page[1], '命中'))
else:
# 缺页
self.page_access_sequence.append(('页表' + str(page[0]), page[1], '缺页'))
self.fault_num += 1
if len(self.page_table1) + len(self.page_table2) < self.num_frames:
# 如果有空页框,把页面装载到此页框
self.page_table1.append(page[1])
self.used1.append(0)
else:
# 如果所有帧都已满,请使用特定的替换算法替换页面
self.replace_page(page)
def access_page2(self, page):
if page[1] in self.page_table2:
# 命中
idx = self.page_table2.index(page[1])
self.used2[idx] += 1
self.page_access_sequence.append(('页表' + str(page[0]), page[1], '命中'))
else:
# 缺页
self.page_access_sequence.append(('页表' + str(page[0]), page[1], '缺页'))
self.fault_num += 1
if len(self.page_table1) + len(self.page_table2) < self.num_frames:
# 如果有空页框,把页面装载到此页框
self.page_table2.append(page[1])
self.used2.append(0)
else:
# 如果所有帧都已满,请使用特定的替换算法替换页面
self.replace_page(page)
def replace_page(self, page):
pass # 局部页替换策略和全局页替换策略有差异
def page_missing_rate(self):
# 计算缺页率
print("缺页率为:")
print(self.fault_num / len(self.page_access_sequence))
class LocalPageReplacementSimulator(PageReplacementSimulator):
# 局部页面替换模拟器
def __init__(self, num_pages, num_frames):
super().__init__(num_pages, num_frames)
def replace_page(self, page):
if page[0] == 1:
minx = min(self.used1)
inx_min = self.used1.index(minx)
self.page_table1[inx_min] = page[1]
self.used1[inx_min] = 0
else:
minx = min(self.used2)
inx_min = self.used2.index(minx)
self.page_table2[inx_min] = page[1]
self.used2[inx_min] = 0
class GlobalPageReplacementSimulator(PageReplacementSimulator):
# 全局页面替换模拟器
def __init__(self, num_pages, num_frames):
super().__init__(num_pages, num_frames)
def replace_page(self, page):
self.used = self.used1 + self.used2
inx_min = self.used.index(min(self.used))
if inx_min < len(self.page_table1):
self.page_table1[inx_min] = page[1]
self.used1[inx_min] = 0
else:
self.page_table2[inx_min - len(self.page_table1)] = page[1]
self.used1[inx_min - 5] = 0
class page_access_sequence:
# 基于统计模型的页面访问串
def __init__(self, length, probabilities1, probabilities2):
self.length = length# 访问串长度
self.probabilities1 = probabilities1# 每个状态相关的概率
self.probabilities2 = probabilities2
self.page_access_sequence = []
def make_access(self):
self.page_access_sequence.append([random.randint(1, 2), random.randint(0, 4)])
# 随机生成第一个访问的页面
for i in range(self.length - 1):
inx1 = self.page_access_sequence[i][0]
inx2 = self.page_access_sequence[i][1]
if inx1 == 1:
if random.random() <= probabilities1[inx2]:
# 每个状态相关的概率代表下一次访问任指向同一页面的概率
self.page_access_sequence.append(self.page_access_sequence[i])
else:
# 否则,下次将以等概率访问其他任何一个页面
self.page_access_sequence.append([random.randint(1, 2), random.randint(0, 4)])
else:
if random.random() <= probabilities2[inx2]:
self.page_access_sequence.append(self.page_access_sequence[i])
else:
self.page_access_sequence.append([random.randint(1, 2), random.randint(0, 4)])
if __name__ == "__main__":
num_pages1 = 5
num_pages2 = 5
num_pages = num_pages1 + num_pages2
num_frames = 6
sequence_length = 40
probabilities1 = [0.4, 0.2, 0.1, 0.1, 0.2]
probabilities2 = [0.3, 0.2, 0.1, 0.1, 0.3]
page_access = page_access_sequence(sequence_length, probabilities1, probabilities2)
page_access.make_access()
local_simulator = LocalPageReplacementSimulator(num_pages, num_frames)
global_simulator = GlobalPageReplacementSimulator(num_pages, num_frames)
for i in range(sequence_length):
local_simulator.access_page(page_access.page_access_sequence[i])
global_simulator.access_page(page_access.page_access_sequence[i])
print("局部页置换策略:")
print(local_simulator.page_access_sequence)
local_simulator.page_missing_rate()
print("\n全局页置换策略:")
print(global_simulator.page_access_sequence)
global_simulator.page_missing_rate()
结果:
思路解析:
PageReplacementSimulator 类是页面置换模拟器的基类,包括了页面访问和页面置换的基本逻辑。它包括了一个用于存储页面表和页面访问序列的属性,以及 access_page 和 replace_page 两个方法。
LocalPageReplacementSimulator 类是 PageReplacementSimulator 的子类,实现了局部页面置换算法的模拟。它包括了一个用于生成页面访问序列的方法 generate_access_sequence,在这个方法中根据一定的概率规则来模拟页面的访问。
GlobalPageReplacementSimulator 类也是 PageReplacementSimulator 的子类,实现了全局页面置换算法的模拟。它同样包括了一个用于生成页面访问序列的方法 generate_access_sequence,在这个方法中直接随机访问页面。
page_access_sequence 类是页面访问序列,生成一个基于统计模型的页面访问串。