计算机操作系统之页面置换算法课程设计(python实现,可运行有界面程序exe)
(前言:这是本人19年12月份完成的计算机操作系统课程报告,也是第一次用python实现有界面应用程序,虽然还很low,但是于我而言意义重大,特写下此文纪念。这也是我第一次写博客,有不足之处多多指教。)
一、课程设计的目的和意义
通过编写一个程序,模拟系统的存储器页面置换,来深入理解最佳置换算法(Optimal)、先进先出置换算法(FIFO)以及最近最久未使用算法(LRU)的基本原理。同时巩固编程基础,提高解决问题能力。
二、方案设计及开发过程
1. 页面置换算法的由来
为了能支持虚拟存储器功能,而增加了请求调页功能和页面置换功能。在进程运行过程中,若其所要访问的页面不在内存,而需要把它们调入内存,但内存已无空闲空间时,为了保证该进程能正常运行,系统必须从内存中调出一页程序或数据送到磁盘的对换区中。但应将哪个页面调出,须根据一点过的算法来确定,这就是页面置换算法。
2. 页面置换算法介绍
本次课程设计主要介绍三种页面置换算法:OPT最佳置换算法、FIFO先进先出置换算法和LRU最近最久未使用置换算法。
(1).最佳置换算法(Optimal)
从主存中移出永远不再需要的页面;如无这样的页面存在,则选择最长时间不需要访问的页面。于所选择的被淘汰页面将是以后永不使用的,或者是在最长时间内不再被访问的页面,这样可以保证获得最低的缺页率。
(2).先进先出置换算法(FIFO)
是最简单的页面置换算法。这种算法的基本思想是:当需要淘汰一个页面时,总是选择驻留主存时间最长的页面进行淘汰,即先进入主存的页面先淘汰。其理由是:最早调入主存的页面不再被使用的可能性最大。
(3).最近最久未使用置换算法(LRU)
这种算法的基本思想是:利用局部性原理,根据一个作业在执行过程中过去的页面访问历史来推测未来的行为。它认为过去一段时间里不曾被访问过的页面,在最近的将来可能也不会再被访问。所以,这种算法的实质是:当需要淘汰一个页面时,总是选择在最近一段时间内最久不用的页面予以淘汰。 LRU性能较好,但需要寄存器和栈的硬件支持。
3. 算法流程图
(1) OPT页面置换算法流程图
(2)FIFO页面置换算法流程图
(3)LRU置换算法流程图
4. 编程思路
(1)最佳置换算法(Optimal)
1.定义一个OPT类,传入参数cin (string)和input_n(int),分别代表序列号和页表物理块数。
2.将cin切片分割得到序列号存入列表list_xuLie。
3.遍历list_xuLie中每一个页面[i],判断[i]是否已在页表list_yeBiao中:若已在,则什么也不做,查找下一个;若不在,再判断页表是否已满:若未满,则将该页面添加至页表末;若已满,则在list_xuLie中查找[i]之后是否存在不再使用的页面:若存在,则将list_yeBiao中的该页面置换为[i],若不存在,则在list_xuLie中查找[i]之后最久不使用的页面,并将该页面替换为[i]。
4.输出每一次遍历的list_yeBiao,和是否缺页。
5.输出总的缺页次数和缺页率。
(2)先进先出置换算法(FIFO)
1.定义一个FIFO类,传入参数cin (string)和input_n(int),分别代表序列号和页表物理块数。
2.将cin切片分割得到序列号存入列表list_xuLie。
3.遍历list_xuLie中每一个页面[i],判断[i]是否已在页表list_yeBiao中:若已在,则pass;若不在,则判断页表是否已满:若未满,则将该页面添加至页表末;若已满,则将list_yeBiao中第一页删除,其他的页面前移,并将该页面添加至页表末。
4.输出每一次遍历的list_yeBiao,和是否缺页。
5.输出总的缺页次数和缺页率。
(3)最近最久未使用置换算法(LRU)
1.定义一个OPT类,传入参数cin (string)和input_n(int),分别代表序列号和页表物理块数。
2.将cin切片分割得到序列号存入列表list_xuLie。
3.遍历list_xuLie中每一个页面[i],判断[i]是否已在页表list_yeBiao中:若已在,将该页面移到页表末;若不在,再判断页表是否已满:若未满,则将该页面添加至页表末;若已满,则删除list_xuLie中第一个页面,其他的页面前移,并将该页面添加至页表末。
4.输出每一次遍历的list_yeBiao,和是否缺页。
5.输出总的缺页次数和缺页率。
(4)制作界面及调用函数
1.利用python的一个扩展工具叫PyQt5设计界面。
2.界面中包含四个文本框:内存物理块数文本输入框、页面序列文本输入框、算法过程和结果文本展示框、算法介绍文本展示框;包含六个功能按钮:OPT算法按钮、FIFO算法按钮、LRU算法按钮、保存文件按钮、清空文件按钮、退出程序按钮;以及各标签。
3.Py UIC将得到的ui格式转换为pycharm打开的py格式。
4.Import 上述三个算法的py文件并调用,完善各按钮功能。
(5)完善程序
1.增加异常捕获机制,针对各种非法输入能够报错并保证程序的正常运行。
2.增加保存功能,可以将输入的和输出的以及算法名称保存到txt文件中。
3.增加清空功能,可以将输入和输出全部清空。
4.增加退出功能,点击直接退出程序。
三、调试记录与分析
1.打开程序界面
说明:刚打开程序,文本输入框和展示框均为空。
2.输入为空时
说明:当点击选择算法按钮时,总是显示算法介绍,但是当输入为空时,异常捕获实现提示先输入,保证程序继续正常运行。
3.非法输入时
说明:当点击选择算法按钮时,显示算法介绍,但是当输入非法时,异常捕获实现提示输入数字,并用空格隔开,保证程序继续正常运行。
4.正常输入时,点击OPT按钮
说明:当点击OPT按钮时,显示OPT算法介绍,异常捕获未发现异常时,调用OPT算法函数,将输出赋值给文本浏览框显示出来。
5.正常输入时,点击FIFO按钮
说明:当点击FIFO按钮时,显示FIFO算法介绍,异常捕获未发现异常时,调用FIFO算法函数,将输出赋值给文本浏览框显示出来。
6.正常输入时,点击LRU按钮
说明:当点击LRU按钮时,显示LRU算法介绍,异常捕获未发现异常时,调用LRU算法函数,将输出赋值给文本浏览框显示出来。
7.点击save保存按钮
说明:点击保存按钮,调用QFileDialog.getSaveFileNameh函数弹出窗口选择保存路径和保存的文件名。
说明:保存成功后,提示保存成功,显示文件名及保存路径。
说明:文件内容包括:输入的内存块数、页面序号、文本浏览框内的内容,以及算法名称。
8.点击clear清空按钮
说明:点击clear清空按钮实现清空所有输入及输出。
9.点击quit退出按钮
说明:点击quit退出按钮,调用系统的退出程序,等同于右上角的关闭按钮。
四、程序源代码及关键注释
(1)FIFO算法代码:FIFO.py
class FIFO(object):
list_input = [] # 存放页面访问序列
flag = True # True表示缺页
count = 0 # 计算缺页次数
n = 0 # 页面数
def __init__(self, cin, input_n):
self.m = input_n
self.cin = cin
self.list_yeBiao = [] # 主存块中存在的页面号列表
self.c_out = ""
self.gg = False
def getinfo(self):
try:
self.list_input = self.cin.split(' ') # 存放页面访问次序的列表
self.n = len(self.list_input)
self.m = int(self.m)
if self.m < 1:
raise ValueError
for j in range(len(self.list_input)):
self.list_input[j] = int(self.list_input[j])
except TypeError and ValueError:
self.gg = True
else:
self.gg = False
def compute(self):
self.getinfo()
if self.gg is False:
for i in range(len(self.list_input)):
if self.list_input[i] not in self.list_yeBiao:
self.flag = True # True表示缺页
if len(self.list_yeBiao) < self.m: # 如果list_yeBiao的长度还没到达m
self.list_yeBiao[len(self.list_yeBiao)::] = [self.list_input[i]]
# 就在其尾部添加i 也可以写成self.list_yeBiao.append(i)
else: # 如果list_yeBiao的长度已经到达m了
self.list_yeBiao[0:len(self.list_yeBiao) - 1:] = self.list_yeBiao[1:len(self.list_yeBiao):]
# 从第二位起前移
self.list_yeBiao[len(self.list_yeBiao) - 1] = self.list_input[i] # 把最后一个改为self.list_input[i]
self.count += 1 # 缺页计数+1
else: # 如果i在list_yeBiao中,即不缺页
self.flag = False # 表示不缺页
# print(self.list_yeBiao, '缺页了' if self.flag is True else '不缺页')
if self.flag is True:
self.c_out += str("缺页了" + str(self.list_yeBiao) + '\n')
else:
self.c_out += str("不缺页" + str(self.list_yeBiao) + '\n')
# print('缺页次数为%d,缺页率为%f%%,页面置换次数为%d' % (self.count, self.count / self.n * 100, self.count - self.m))
self.c_out += str('缺页次数为%d,缺页率为%f%%,页面置换次数为%d' % (self.count, self.count / self.n * 100, self.count - self.m))
else:
self.c_out = ('请输入数字,并用空格隔开,您输入的是:\n %s \n %s' % (self.m, self.cin))
return self.c_out
# sss = "1 2 3 4 5 6 7 n 3 8 5 1 2 3 1 2 3 4 5"
# nini = FIFO(sss, 3).compute()
# print(nini)
(2)OPT算法代码:OPT_New.py
class OPT(object):
flag = True # True表示缺页
count = 0 # 计算缺页次数
n = 0 # 序列中总的页面数
ma = 0 # list_xuLie[ma]是最久不用的页面
s = 0 # 置换list_yeBiao[s]
w = True
def __init__(self, cin, input_n):
self.m = input_n
self.cin = cin
self.list_xuLie = [] # 页面序列列表
self.list_yeBiao = [] # 主存块中存在的页面号列表
self.c_out = ""
self.mutex = True
self.gg = False
def getinfo(self):
try:
self.list_xuLie = self.cin.split(' ') # 存放页面访问次序的列表
self.m = int(self.m)
self.n = len(self.list_xuLie)
if self.m < 1:
raise ValueError
for j in range(len(self.list_xuLie)):
self.list_xuLie[j] = int(self.list_xuLie[j])
except TypeError and ValueError:
self.gg = True
# print(self.list_xuLie, self.n)
def compute(self):
self.getinfo()
if self.gg is True:
self.c_out = ('请输入数字,并用空格隔开,您输入的是:\n %s \n %s' % (self.m, self.cin))
else:
for i in range(len(self.list_xuLie)):
self.s = 0
if self.list_xuLie[i] not in self.list_yeBiao:
self.flag = True # True表示缺页
if len(self.list_yeBiao) < self.m: # 如果list_yeBiao的长度还没到达m
self.list_yeBiao[len(self.list_yeBiao)::] = [self.list_xuLie[i]] # 就在其尾部添加i 也可以写成self.list_yeBiao.append(i)
else: # 如果list_yeBiao的长度已经到达m了
for t in range(self.m): # 寻找剩余页面列表中没有出现的序号并替换
if self.list_yeBiao[t] not in self.list_xuLie[i:self.n]:
self.s = t
self.w = False
break # 找到第一个符合的就替换,若没有break则是将最后一个替换
if self.w is True:
self.ma = 0
for t in range(self.m): # 寻找剩余页面列表中最后出现的序号并替换
self.mutex = True
for y in range(i, len(self.list_xuLie)):
if self.list_yeBiao[t] == self.list_xuLie[y]:
self.mutex = False
if y > self.ma:
self.ma = y
self.s = t
break # 找到首次出现的序列号就结束循环
else:
break # 若没有则继续下个循环
if not self.mutex:
break
self.list_yeBiao[self.s] = self.list_xuLie[i] # 将内存中的最久不使用的页面号替换
self.count += 1 # 缺页计数+1
else: # 如果i在list_yeBiao中,即不缺页
self.flag = False # 表示不缺页
# print(self.list_yeBiao, '缺页了' if self.flag is True else '不缺页')
if self.flag is True:
self.c_out += str("缺页了" + str(self.list_yeBiao) + '\n')
else:
self.c_out += str("不缺页" + str(self.list_yeBiao) + '\n')
# print('缺页次数为%d,缺页率为%f%%,页面置换次数为%d' % (self.count, self.count / self.n * 100, self.count - self.m))
self.c_out += str('缺页次数为%d,缺页率为%f%%,页面置换次数为%d' % (self.count, self.count / self.n * 100, self.count - self.m))
return self.c_out
# sss = "1 2 3 4 5 6 7 8 9 3 4 7 5 4 6 7"
# nini = OPT(sss, 5).compute()
# print(nini)
(3)LRU算法代码:LRU_New.py
class LRU(object):
def __init__(self, cin, input_n):
self.cin = cin
self.m = input_n
def compute(self):
c_out = ""
try:
self.m = int(self.m)
if self.m < 1:
raise ValueError
list_xuLie = self.cin.split(' ') # 存放页面访问次序的列表
for i in range(len(list_xuLie)):
list_xuLie[i] = int(list_xuLie[i])
list_yeBiao = [] # 列表list_yeBiao最多(在填满后不多不少)m个元素,用来实现LRU算法
count = 0 # count用于计算缺页次数
flag = True # True表示缺页
n = len(list_xuLie)
except TypeError and ValueError:
c_out = ('请输入数字,并用空格隔开,您输入的是:\n %s \n %s' % (self.m, self.cin))
else:
for i in list_xuLie: # i从list_xuLie的第一个元素开始
if i not in list_yeBiao: # 如果i不在list_yeBiao中,即缺页
flag = True # 表示缺页
if len(list_yeBiao) < self.m: # 如果list_yeBiao的长度还没到达m
list_yeBiao[len(list_yeBiao)::] = [i] # 就在其尾部添加i
else: # 如果list_yeBiao的长度已经到达m了
list_yeBiao[0:self.m - 1:] = list_yeBiao[1:self.m:]
# 将list_yeBiao[1]到list_yeBiao[self.m-1]复制到list_yeBiao[0]到list_yeBiao[self.m-2]
list_yeBiao[self.m - 1::] = [i] # 将i放入list_yeBiao[self.m-1]的位置
count += 1 # 缺页的,记录之
else: # 如果i在list_yeBiao中,即不缺页,将i转移到页表最后
flag = False # 表示不缺页
list_yeBiao[list_yeBiao.index(i):len(list_yeBiao) - 1:] = list_yeBiao[list_yeBiao.index(i) + 1::]
# 将i之后的元素都复制到i开始向后的位置,并在最后留一个空位保证不改变list_yeBiao长度
list_yeBiao[len(list_yeBiao) - 1::] = [i] # 将最后一个元素用i覆盖
# print(list_yeBiao, "缺页了" if flag is True else "不缺页")
if flag is True:
c_out += str("缺页了" + str(list_yeBiao) + '\n')
else:
c_out += str("不缺页" + str(list_yeBiao) + '\n')
# print("LRU算法结束,总的缺页次数为", count)
c_out += str('缺页次数为%d,缺页率为%f%%,页面置换次数为%d' % (count, count / n * 100, count - self.m))
finally:
return c_out
# ssss = "1 2 3 4 5 6 7 8 9 1 2 3 4 5 2 3 4 5 6 7 8 2 3"
# print(LRU(ssss, 5).compute())
(4)主界面程序代码:PRA_New.py
# -*- coding: utf-8 -*-
# Form implementation generated from reading ui file 'PRA.ui'
#
# Created by: PyQt5 UI code generator 5.13.0
#
# WARNING! All changes made in this file will be lost!
from PyQt5 import QtCore, QtGui, QtWidgets
import sys
from PyQt5.QtWidgets import QApplication, QMainWindow, QFileDialog
import LRU_New, FIFO, OPT_New
class Ui_MainWindow(object):
introduce_OPT = "最佳置换算法\n Optimal\n 所选择的被淘汰页面将是以后永不使用的," \
"或者是在最长时间内不再被访问的页面,这样可以保证获得最低的缺页率。" \
"是一种理想的页面置换算法,但是因为无法预知未来,因此现实中无法实现。"
introduce_LRU = "最近最久未使用置换算法\n LRU(Least Recently Used)\n 当需要" \
"淘汰一个页面时,总是选择在最近一段时间内最久不用的页面予以淘汰。 " \
"LRU性能较好,但需要寄存器和栈的硬件支持。"
introduce_FIFO = "先进先出置换算法\n FIFO(First In First Out)\n 当需要淘汰一个页面时," \
"总是选择驻留主存时间最长的页面进行淘汰,即先进入主存的页面先淘汰。" \
"其理由是:最早调入主存的页面不再被使用的可能性最大。"
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(720, 591)
self.centralwidget = QtWidgets.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
self.widget = QtWidgets.QWidget(self.centralwidget)
self.widget.setGeometry(QtCore.QRect(20, 0, 664, 532))
self.widget.setObjectName("widget")
self.horizontalLayout_5 = QtWidgets.QHBoxLayout(self.widget)
self.horizontalLayout_5.setContentsMargins(0, 0, 0, 0)
self.horizontalLayout_5.setObjectName("horizontalLayout_5")
spacerItem = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
self.horizontalLayout_5.addItem(spacerItem)
self.verticalLayout_6 = QtWidgets.QVBoxLayout()
self.verticalLayout_6.setObjectName("verticalLayout_6")
spacerItem1 = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding)
self.verticalLayout_6.addItem(spacerItem1)
self.horizontalLayout_4 = QtWidgets.QHBoxLayout()
self.horizontalLayout_4.setObjectName("horizontalLayout_4")
self.verticalLayout_2 = QtWidgets.QVBoxLayout()
self.verticalLayout_2.setObjectName("verticalLayout_2")
self.verticalLayout = QtWidgets.QVBoxLayout()
self.verticalLayout.setObjectName("verticalLayout")
self.horizontalLayout = QtWidgets.QHBoxLayout()
self.horizontalLayout.setObjectName("horizontalLayout")
self.label_1 = QtWidgets.QLabel(self.widget)
self.label_1.setObjectName("label_1")
self.horizontalLayout.addWidget(self.label_1)
self.lineEdit_n = QtWidgets.QLineEdit(self.widget)
self.lineEdit_n.setObjectName("lineEdit_n")
self.horizontalLayout.addWidget(self.lineEdit_n)
self.verticalLayout.addLayout(self.horizontalLayout)
self.label_2 = QtWidgets.QLabel(self.widget)
self.label_2.setObjectName("label_2")
self.verticalLayout.addWidget(self.label_2)
self.lineEdit_input = QtWidgets.QLineEdit(self.widget)
self.lineEdit_input.setObjectName("lineEdit_input")
self.verticalLayout.addWidget(self.lineEdit_input)
self.verticalLayout_2.addLayout(self.verticalLayout)
self.line = QtWidgets.QFrame(self.widget)
self.line.setFrameShape(QtWidgets.QFrame.HLine)
self.line.setFrameShadow(QtWidgets.QFrame.Sunken)
self.line.setObjectName("line")
self.verticalLayout_2.addWidget(self.line)
self.textBrowser_print = QtWidgets.QTextBrowser(self.widget)
self.textBrowser_print.setObjectName("textBrowser_print")
self.verticalLayout_2.addWidget(self.textBrowser_print)
self.horizontalLayout_4.addLayout(self.verticalLayout_2)
self.line_6 = QtWidgets.QFrame(self.widget)
self.line_6.setFrameShape(QtWidgets.QFrame.VLine)
self.line_6.setFrameShadow(QtWidgets.QFrame.Sunken)
self.line_6.setObjectName("line_6")
self.horizontalLayout_4.addWidget(self.line_6)
self.verticalLayout_5 = QtWidgets.QVBoxLayout()
self.verticalLayout_5.setObjectName("verticalLayout_5")
self.textBrowser_introduce = QtWidgets.QTextBrowser(self.widget)
self.textBrowser_introduce.setObjectName("textBrowser_introduce")
self.verticalLayout_5.addWidget(self.textBrowser_introduce)
self.line_4 = QtWidgets.QFrame(self.widget)
self.line_4.setFrameShape(QtWidgets.QFrame.HLine)
self.line_4.setFrameShadow(QtWidgets.QFrame.Sunken)
self.line_4.setObjectName("line_4")
self.verticalLayout_5.addWidget(self.line_4)
self.horizontalLayout_2 = QtWidgets.QHBoxLayout()
self.horizontalLayout_2.setObjectName("horizontalLayout_2")
self.label = QtWidgets.QLabel(self.widget)
self.label.setObjectName("label")
self.horizontalLayout_2.addWidget(self.label)
self.line_2 = QtWidgets.QFrame(self.widget)
self.line_2.setFrameShape(QtWidgets.QFrame.VLine)
self.line_2.setFrameShadow(QtWidgets.QFrame.Sunken)
self.line_2.setObjectName("line_2")
self.horizontalLayout_2.addWidget(self.line_2)
self.verticalLayout_4 = QtWidgets.QVBoxLayout()
self.verticalLayout_4.setObjectName("verticalLayout_4")
self.pushButton_OPT = QtWidgets.QPushButton(self.widget)
self.pushButton_OPT.setObjectName("pushButton_OPT")
self.verticalLayout_4.addWidget(self.pushButton_OPT)
self.pushButton_FIFO = QtWidgets.QPushButton(self.widget)
self.pushButton_FIFO.setObjectName("pushButton_FIFO")
self.verticalLayout_4.addWidget(self.pushButton_FIFO)
self.pushButton_LRU = QtWidgets.QPushButton(self.widget)
self.pushButton_LRU.setObjectName("pushButton_LRU")
self.verticalLayout_4.addWidget(self.pushButton_LRU)
self.horizontalLayout_2.addLayout(self.verticalLayout_4)
self.verticalLayout_5.addLayout(self.horizontalLayout_2)
self.line_5 = QtWidgets.QFrame(self.widget)
self.line_5.setFrameShape(QtWidgets.QFrame.HLine)
self.line_5.setFrameShadow(QtWidgets.QFrame.Sunken)
self.line_5.setObjectName("line_5")
self.verticalLayout_5.addWidget(self.line_5)
self.horizontalLayout_3 = QtWidgets.QHBoxLayout()
self.horizontalLayout_3.setObjectName("horizontalLayout_3")
self.label_3 = QtWidgets.QLabel(self.widget)
self.label_3.setObjectName("label_3")
self.horizontalLayout_3.addWidget(self.label_3)
self.line_3 = QtWidgets.QFrame(self.widget)
self.line_3.setFrameShape(QtWidgets.QFrame.VLine)
self.line_3.setFrameShadow(QtWidgets.QFrame.Sunken)
self.line_3.setObjectName("line_3")
self.horizontalLayout_3.addWidget(self.line_3)
self.verticalLayout_3 = QtWidgets.QVBoxLayout()
self.verticalLayout_3.setObjectName("verticalLayout_3")
self.pushButton_save = QtWidgets.QPushButton(self.widget)
self.pushButton_save.setObjectName("pushButton_save")
self.verticalLayout_3.addWidget(self.pushButton_save)
self.pushButton_clear = QtWidgets.QPushButton(self.widget)
self.pushButton_clear.setObjectName("pushButton_clear")
self.verticalLayout_3.addWidget(self.pushButton_clear)
self.pushButton_quit = QtWidgets.QPushButton(self.widget)
self.pushButton_quit.setObjectName("pushButton_quit")
self.verticalLayout_3.addWidget(self.pushButton_quit)
self.horizontalLayout_3.addLayout(self.verticalLayout_3)
self.verticalLayout_5.addLayout(self.horizontalLayout_3)
self.horizontalLayout_4.addLayout(self.verticalLayout_5)
self.verticalLayout_6.addLayout(self.horizontalLayout_4)
spacerItem2 = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding)
self.verticalLayout_6.addItem(spacerItem2)
self.horizontalLayout_5.addLayout(self.verticalLayout_6)
spacerItem3 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
self.horizontalLayout_5.addItem(spacerItem3)
MainWindow.setCentralWidget(self.centralwidget)
self.menubar = QtWidgets.QMenuBar(MainWindow)
self.menubar.setGeometry(QtCore.QRect(0, 0, 720, 26))
self.menubar.setObjectName("menubar")
MainWindow.setMenuBar(self.menubar)
self.statusbar = QtWidgets.QStatusBar(MainWindow)
self.statusbar.setObjectName("statusbar")
MainWindow.setStatusBar(self.statusbar)
self.label_1.setBuddy(self.lineEdit_n)
self.label_2.setBuddy(self.lineEdit_input)
self.pushButton_OPT.clicked.connect(self.OPT_button)
self.pushButton_FIFO.clicked.connect(self.FIFO_button)
self.pushButton_LRU.clicked.connect(self.LRU_button)
self.pushButton_save.clicked.connect(self.save_button)
self.pushButton_clear.clicked.connect(self.clear_button)
self.pushButton_quit.clicked.connect(self.quit_button)
self.retranslateUi(MainWindow)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
def retranslateUi(self, MainWindow):
_translate = QtCore.QCoreApplication.translate
MainWindow.setWindowTitle(_translate("MainWindow", "计算机操作系统之页面置换算法-计算机172-1530332103-王磊"))
self.label_1.setText(_translate("MainWindow", "请输入内存块数"))
self.label_2.setText(_translate("MainWindow", "请输入页面序号:"))
self.label.setText(_translate("MainWindow", "选择算法:"))
self.pushButton_OPT.setText(_translate("MainWindow", "OPT"))
self.pushButton_FIFO.setText(_translate("MainWindow", "FIFO"))
self.pushButton_LRU.setText(_translate("MainWindow", "LRU"))
self.label_3.setText(_translate("MainWindow", "其他操作:"))
self.pushButton_save.setText(_translate("MainWindow", "save"))
self.pushButton_clear.setText(_translate("MainWindow", "clear"))
self.pushButton_quit.setText(_translate("MainWindow", "quit"))
def OPT_button(self):
try:
self.textBrowser_print.clear() # 清空显示框
self.textBrowser_introduce.clear() # 清空描述框
input_text = self.lineEdit_input.text() # 赋值输入页面序号
input_n = self.lineEdit_n.text() # 赋值输入的内存块数
if len(input_text) == 0 or len(input_n) == 0:
raise EmptyException_input
except EmptyException_input as result:
self.textBrowser_print.append(result.out)
else:
out_print = OPT_New.OPT(input_text, input_n).compute() # 赋值输出
self.textBrowser_print.append(out_print) # 显示输出
finally:
self.textBrowser_print.append("end")
self.textBrowser_introduce.append(self.introduce_OPT) # 显示算法描述
def FIFO_button(self):
try:
self.textBrowser_print.clear() # 清空显示框
self.textBrowser_introduce.clear() # 清空描述框
input_text = self.lineEdit_input.text() # 赋值输入
input_n = self.lineEdit_n.text() # 赋值输入的内存块数
if len(input_text) == 0 or len(input_n) == 0:
raise EmptyException_input
except EmptyException_input as result:
self.textBrowser_print.append(result.out)
else:
out_print = FIFO.FIFO(input_text, input_n).compute()
self.textBrowser_print.append(out_print)
finally:
self.textBrowser_print.append("end")
self.textBrowser_introduce.append(self.introduce_FIFO)
def LRU_button(self):
try:
self.textBrowser_print.clear() # 清空显示框
self.textBrowser_introduce.clear() # 清空描述框
input_text = self.lineEdit_input.text() # 赋值输入
input_n = self.lineEdit_n.text() # 赋值输入的内存块数
if len(input_text) == 0 or len(input_n) == 0:
raise EmptyException_input
except EmptyException_input as result:
self.textBrowser_print.append(result.out)
else:
out_print = LRU_New.LRU(input_text, input_n).compute()
self.textBrowser_print.append(out_print)
finally:
self.textBrowser_print.append("end")
self.textBrowser_introduce.append(self.introduce_LRU)
def save_button(self):
try: # 防止没有选择保存路径而导致程序中断
filename, filter_ = QFileDialog.getSaveFileName(None, 'save file', filter='*.txt')
with open(filename, 'w') as f:
my_text = self.textBrowser_introduce.toPlainText()[0:12] + self.lineEdit_n.text() + '\n' + self.lineEdit_input.text() + '\n' + self.textBrowser_print.toPlainText()
f.write(my_text)
except Exception:
pass
else:
self.textBrowser_print.append('保存成功\n文件保存在:\n%s' % filename)
def clear_button(self):
self.lineEdit_n.clear()
self.lineEdit_input.clear()
self.textBrowser_print.clear()
self.textBrowser_introduce.clear()
def quit_button(self):
sys.exit(app.exec_())
class EmptyException_input(Exception):
def __init__(self):
self.out = "请先输入页表物理块号和页面访问序列号!!!"
if __name__ == '__main__':
app = QApplication(sys.argv)
MainWindow = QMainWindow()
ui = Ui_MainWindow()
ui.setupUi(MainWindow)
MainWindow.show()
sys.exit(app.exec_())
五、总结
这是我用python实现的第一个有界面的应用程序,编程过程中遇到过很多问题,尤其是对于我这个刚入门python的小白来说,过程可以说是非常痛苦的。一开始,很多语法都要慢慢摸索,反复的试验,了解基本的数据结构及其用法,例如列表(list)、字典(dict)等是必须掌握的。一开始如何将输入的字符串切片,转换为int整型,存入列表;然后利用for 循环遍历,循环套循环,if语句判断也是一层套一层,脑袋都快炸了(可能是因为我的知道的python内嵌函数还是太少了所以这么麻烦);到后面的怎么控制输出以及界面的制作。遇到的error不计其数,但是还是一步步通过查找资料不断学习并解决了这些问题。借这次机会,理解页面置换算法原理的同时,也很大程度提高了我的编程思维和技能,让我从中感受到了无穷的乐趣,总之,这次课程设计对我意义十分重大。