赞
踩
目录
(3)LRU(Least Recently Used)置换算法
编译软件:pycharm
程序语言:python
设计程序模拟先进先出FIFO、最佳置换OPI和最近最久未使用LRU页面置换算法的工作过程。假设内存中分配给每个进程的最小物理块数为m,在进程运行过程中要访问的页面个数为n,页面访问序列为P1, … ,Pn,分别利用不同的页面置换算法调度进程的页面访问序列,给出页面访问序列的置换过程,计算每种算法缺页次数和缺页率。
1)利用先进先出FIFO、最佳置换OPI和最近最久未使用LRU三种页面置换算法模拟页面访问过程。
2)模拟三种算法的页面置换过程,给出每个页面访问时的内存分配情况。
3)输入:最小物理块数m,页面个数n,页面访问序列P1, … ,Pn,算法选择1-FIFO,2-OPI,3-LRU。
4)输出:每种算法的缺页次数和缺页率。
用C++语言实现提示:
1)程序中进程调度时间变量描述如下:
- MaxNumber = 100
- PageOrder = np.zeros(MaxNumber, dtype=int) # 页面序列 创建了一个长度为MaxNumber的整数型数组,并将所有元素初始化为零。
- PageNum = 0 # 页面个数
- LackNum = 0 # 缺页次数
- MinBlockNum = 0 # 最小物理块数
- PageDisCount = np.zeros(MaxNumber, dtype=int) # 当前内存距离下一次出现的距离
- LRUtime = np.zeros(MaxNumber, dtype=int) # 存储队列中各个页面最近使用情况
-
- LackPageRate = 0.0 # 缺页率
- LackPageNum = 0 # 缺页数
- VirtualQueue = np.zeros(MaxNumber, dtype=int) # 虚拟队列
2)进程调度的实现过程如下:
按照页面号引用串的顺序,依次将物理块装入页面中,当装入下一个物理块,发现当页面已满时,将在最长时间内不再被访问的页面换出。
- def OPI():
- #缺页数、缺页率、虚拟列表、当前内存距离下一次出现的距离
- global LackPageNum, LackPageRate, VirtualQueue, PageDisCount
- print("********* 你选择了OPI算法:********* ")
- print("页面置换情况如下:")
- initial()
-
- isInQueue = False
- point = 0#指向最长时间未被访问的下标
- for i in range(MinBlockNum, PageNum):
- isInQueue = PageOrder[i] in VirtualQueue
-
- if not isInQueue:
- LackPageNum += 1
- for s in range(MinBlockNum):
- dis = 1#表示队列每个值距离下一次访问的距离
- # 从页面序列的第i个位置开始找起
- for t in range(i, PageNum):
- if VirtualQueue[s] != PageOrder[t]:
- dis += 1
- else:
- break
- PageDisCount[s] = dis
- #指向当前虚拟列表中数据在后面最晚出现的
- point = np.argmax(PageDisCount)
-
- VirtualQueue[point] = PageOrder[i]
- display()
-
- LackPageRate = LackPageNum / PageNum
- print(f"缺页数LackPageNum = {LackPageNum}")
- print(f"缺页率LackPageRate = {LackPageRate}")
把一个进程已调入内存的页面按先后次序链接成一个队列,并设置一个指针,使它总是指向最老的页面;每次淘汰最先进入内存的页面,即选择在内存中驻留时间最久的页面予以淘汰。
- def FIFO():
- # 总缺页数、缺页率、虚拟队列
- global LackPageNum, LackPageRate, VirtualQueue
- print("********* 你选择了FIFO算法:********* ")
- print("页面置换情况如下:")
- initial()
-
- isInQueue = False
- point = 0#指向最老的页面
- for i in range(MinBlockNum, PageNum):
- isInQueue = PageOrder[i] in VirtualQueue
- # 如果当前页面不在队列中
- if not isInQueue:
- LackPageNum += 1#缺页数加1
- VirtualQueue[point] = PageOrder[i]
- display()
- point = (point + 1) % MinBlockNum
- #当point指向队尾后一位的时候,将point重新指向队首
-
- LackPageRate = LackPageNum / PageNum
- print(f"缺页数LackPageNum = {LackPageNum}")
- print(f"缺页率LackPageRate = {LackPageRate}")
赋予每个页面一个访问字段,用来记录一个页面自上次被访问以来所经历的时间t。当需淘汰一个页面时,选择现有页面中其t值最大的,即最久未使用的页面予以淘汰。
- def LRU():
- #缺页数、缺页率、虚拟列表、存储队列中各个页面最近使用情况
- global LackPageNum, LackPageRate, VirtualQueue, LRUtime
- print("********* 你选择了LRU算法:********* ")
- print("页面置换情况如下:")
-
- initial()
- isInQueue = False
- point = 0#指向最长时间未被访问的下标
-
-
- for i in range(MinBlockNum, PageNum):
- isInQueue = PageOrder[i] in VirtualQueue#序列第i个页是否在队列里
- #如果不在队列里
- if not isInQueue:
- LackPageNum += 1#缺页数+
- point = np.argmax(LRUtime)#指针指向最久未使用的
- for j in range(MinBlockNum):
- if VirtualQueue[j] != VirtualQueue[point]:
- LRUtime[j] += 1
-
- VirtualQueue[point] = PageOrder[i]#将PageOrder[i]放入VirtualQueue中最久未使用的位置
- LRUtime[point] = 0
-
- display()
- # 如果PageOrder[i]在VirtualQueue中
- else:
- for s in range(MinBlockNum):
- if VirtualQueue[s] != PageOrder[i]:
- LRUtime[s] += 1
- else:
- LRUtime[s] = 0
-
- LackPageRate = LackPageNum / PageNum
- print(f"缺页数LackPageNum = {LackPageNum}")
- print(f"缺页率LackPageRate = {LackPageRate}")
- import numpy as np
-
- MaxNumber = 100
- PageOrder = np.zeros(MaxNumber, dtype=int) # 页面序列 创建了一个长度为MaxNumber的整数型数组,并将所有元素初始化为零。
- PageNum = 0 # 页面个数
- LackNum = 0 # 缺页次数
- MinBlockNum = 0 # 最小物理块数
- PageDisCount = np.zeros(MaxNumber, dtype=int) # 当前内存距离下一次出现的距离
- LRUtime = np.zeros(MaxNumber, dtype=int) # 存储队列中各个页面最近使用情况
-
- LackPageRate = 0.0 # 缺页率
- LackPageNum = 0 # 缺页数
- VirtualQueue = np.zeros(MaxNumber, dtype=int) # 虚拟队列
-
-
- def input_data():
- global MinBlockNum, PageNum, PageOrder
- MinBlockNum = int(input("请输入最小物理块数: "))
- PageNum = int(input("请输入页面个数: "))
- PageOrder = list(map(int, input("请输入页面序列(以空格分隔): ").split()))
-
- print("读取数据结果如下:")
- print(f"最小物理块数 = {MinBlockNum}")
- print(f"页面个数 = {PageNum}")
- print("页面序列如下:")
- print(" ".join(map(str, PageOrder)))
-
-
- def initial():
- # 总缺页数、缺页率、当前内存距离下一次出现的距离、虚拟队列、存储队列中各个页面最近使用情况
- global LackPageNum, LackPageRate, PageDisCount, VirtualQueue, LRUtime
- LackPageNum = MinBlockNum
- LackPageRate = 0.0
-
- PageDisCount = np.zeros(MaxNumber, dtype=int)
- VirtualQueue = np.full(MaxNumber, -1, dtype=int)
- LRUtime = np.zeros(MinBlockNum, dtype=int)
-
- for i in range(MinBlockNum):
- isInQueue2 = VirtualQueue[:i].__contains__(PageOrder[i]) #用于判断PageOrder[i]是否在子列表中
- if not isInQueue2:
- VirtualQueue[i] = PageOrder[i]
- for k in range(i):
- LRUtime[k] += 1#之前的页面对应的时间+1
- display()
- else:
- LRUtime[i] = 0#重新更新为0,表示最近刚刚使用
-
-
- def FIFO():
- # 总缺页数、缺页率、虚拟队列
- global LackPageNum, LackPageRate, VirtualQueue
- print("********* 你选择了FIFO算法:********* ")
- print("页面置换情况如下:")
- initial()
-
- isInQueue = False
- point = 0#指向最老的页面
- for i in range(MinBlockNum, PageNum):
- isInQueue = PageOrder[i] in VirtualQueue
- # 如果当前页面不在队列中
- if not isInQueue:
- LackPageNum += 1#缺页数加1
- VirtualQueue[point] = PageOrder[i]
- display()
- point = (point + 1) % MinBlockNum
- #当point指向队尾后一位的时候,将point重新指向队首
-
- LackPageRate = LackPageNum / PageNum
- print(f"缺页数LackPageNum = {LackPageNum}")
- print(f"缺页率LackPageRate = {LackPageRate}")
-
-
- def OPI():
- #缺页数、缺页率、虚拟列表、当前内存距离下一次出现的距离
- global LackPageNum, LackPageRate, VirtualQueue, PageDisCount
- print("********* 你选择了OPI算法:********* ")
- print("页面置换情况如下:")
- initial()
-
- isInQueue = False
- point = 0#指向最长时间未被访问的下标
- for i in range(MinBlockNum, PageNum):
- isInQueue = PageOrder[i] in VirtualQueue
-
- if not isInQueue:
- LackPageNum += 1
- for s in range(MinBlockNum):
- dis = 1#表示队列每个值距离下一次访问的距离
- # 从页面序列的第i个位置开始找起
- for t in range(i, PageNum):
- if VirtualQueue[s] != PageOrder[t]:
- dis += 1
- else:
- break
- PageDisCount[s] = dis
- #指向当前虚拟列表中数据在后面最晚出现的
- point = np.argmax(PageDisCount)
-
- VirtualQueue[point] = PageOrder[i]
- display()
-
- LackPageRate = LackPageNum / PageNum
- print(f"缺页数LackPageNum = {LackPageNum}")
- print(f"缺页率LackPageRate = {LackPageRate}")
-
-
- def LRU():
- #缺页数、缺页率、虚拟列表、存储队列中各个页面最近使用情况
- global LackPageNum, LackPageRate, VirtualQueue, LRUtime
- print("********* 你选择了LRU算法:********* ")
- print("页面置换情况如下:")
-
- initial()
- isInQueue = False
- point = 0#指向最长时间未被访问的下标
-
-
- for i in range(MinBlockNum, PageNum):
- isInQueue = PageOrder[i] in VirtualQueue#序列第i个页是否在队列里
- #如果不在队列里
- if not isInQueue:
- LackPageNum += 1#缺页数+
- point = np.argmax(LRUtime)#指针指向最久未使用的
- for j in range(MinBlockNum):
- if VirtualQueue[j] != VirtualQueue[point]:
- LRUtime[j] += 1
-
- VirtualQueue[point] = PageOrder[i]#将PageOrder[i]放入VirtualQueue中最久未使用的位置
- LRUtime[point] = 0
-
- display()
- # 如果PageOrder[i]在VirtualQueue中
- else:
- for s in range(MinBlockNum):
- if VirtualQueue[s] != PageOrder[i]:
- LRUtime[s] += 1
- else:
- LRUtime[s] = 0
-
- LackPageRate = LackPageNum / PageNum
- print(f"缺页数LackPageNum = {LackPageNum}")
- print(f"缺页率LackPageRate = {LackPageRate}")
-
-
- def display():
- for i in range(MinBlockNum):
- if VirtualQueue[i] >= 0:
- print(VirtualQueue[i], end=" ")
- print()
-
-
- def main():
- input_data()
-
- isContinue = 1
- while isContinue:
- print("******************************************************")
- print("********* 请选择算法 **********")
- print("********* 1代表FIFO算法 **********")
- print("********* 2代表OPI算法 **********")
- print("********* 3代表LRU算法 **********")
- chooseAlgorithm = int(input())
- if chooseAlgorithm == 1:
- FIFO()
- elif chooseAlgorithm == 2:
- OPI()
- elif chooseAlgorithm == 3:
- LRU()
- else:
- print("请输入正确的序号进行选择:")
-
- print("********** 是否继续选择算法? **********")
- print("********** 输入1代表继续,输入0代表退出! **********")
- isContinue = int(input())
-
- print("***************************结束***************************")
-
-
- if __name__ == "__main__":
- main()
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。