最近老师布置的操作系统实验,用Python实现了一下。下面是具体的数据结构,虽然是用C的思想描述,但区别不大。
1.算法中涉及的数据结构说明
如果采用C语言实现,本设计考虑使用C语言的结构体来描述页表结构和实页的使用情况。
页表结构如下:
VirtualPage | RealPage | State | EnterTime | AccessTime |
其中VirtualPage表示虚页号(因为共10个虚页,所以取值范围是0—9);RealPage表示实页号(取值范围0~n-1,n的值可以在静态指派中事先确定,也可以在运行时动态指派);State表示虚页在内存的状态,值为0表示不在内存,值为1表示虚页已在内存中。EnterTime表示该虚页进入内存的时间(即该虚页进入内存时对应的页地址流编号),AccessTime表示最近一次访问该虚页的时间(即最近一次访问该虚页时对应的页地址流编号)。
实页使用情况表如下:
RealPage | VirtualPage | State |
其中RealPage表示内存块对应的实页号(取值范围0~n-1,n的值可以在静态指派中事先确定,也可以在运行时动态指派);VirtualPage表示该实页中目前存放的虚页号;State表示该实页目前的使用情况:State为0表示目前该实页尚未分配(还没有装虚页),为1表示该实页已分配给VirtualPage所对应的虚页。
此外,为了记录访问虚页的页地址流,需要一个长度为20的一维数组即可。页地址流的顺序可以随机产生。
系统初始化时,页表结构中所有行的RealPage列都置为-1,表示开始所有虚页都没有进入到内存;相应地,所有行的State列都置为0,EnterTime列和AccessTime列也置为0。而实页使用情况表初始化时需要把所有行的VirtualPage置为-1,State置为0,表示开始时所有实页都没有分配出去(即没有装载虚页)。
因为虚页总数在运行前就已知(有10个虚页),因此上述页表总共有10行,可以考虑使用一个结构体数组来表示页表。而实页的情况稍微复杂些。如果运行前实页的数量n可以确定,则属于静态指派实页数的情形,那么实页使用情况表也可以用一个结构体数组来表示。但如果运行前实页的数量n不能确定,而是在程序开始运行时动态指派n的值,则实页使用情况表无法用固定大小的数组来表示,可以考虑链表这种动态数据结构,用链表中的一个节点去表示实页使用情况表中的每一行。为此,每个节点除了要有RealPage、VirtualPage、State域之外,还应增加一个next域用于指向链表的下一个节点。
完整代码
# -*- coding: utf-8 -*-
"""
Created on Mon Nov 22 16:02:24 2021
@author: user
"""
#FIFO && LRU
import random
rpage=[]
vpage=[]
visit=[]
hit=[]
rnum=int(input("input the number of real page:"))
vnum=int(input("input the number of virtual page:"))
vanum=int(input("input the number of virtual page access address:"))
akind=input("input the algorithm of replacement(FIFO/LRU):")
for i in range(vnum):
vpage.append({'virtualPage':i,'realPage':-1,
'state':0,'enterTime':0,'accessTime':0})
for i in range(rnum):
rpage.append({'realPage':i,'virtualPage':-1,'state':0})
for i in range(vanum):
visit.append(random.randint(0,vnum-1))
print('初始化后的虚页页表:')
for i in vpage:
print(i)
print('初始化后的实页使用情况表:')
for i in rpage:
print(i)
print('产生的虚页访问地址流:')
#visit=[2, 4, 6, 1, 8, 8, 2, 0, 2, 8, 4, 3, 9, 5, 9, 3, 9, 9, 1, 7]
#visit=[7, 0, 1, 2, 0, 3, 0, 4, 2, 3, 0, 3, 2, 1, 2, 0, 1, 7, 0, 1]
print(visit)
for i in range(vanum):
print('\n******第{}次访问开始:******'.format(i+1))
print('Access virtual page {}'.format(visit[i]))
print('real page table:')
memory=[]
for m in rpage:
print(m)
memory.append(m['virtualPage'])
print('These virtual pages are in memory:{}'.format(memory))
if visit[i] in memory:
print('virtual page {} is in Memory!'.format(visit[i]))
for z in vpage:
if z['virtualPage']==visit[i]:
z['accessTime']=i+1
hit.append(i+1)
flag=1
else:
print('virtual page {} is not in Memory!'.format(visit[i]))
flag=0
if flag==0:
for n in rpage:
if n['state']==0:
print('real page {} is empty!'.format(n['realPage']))
instead_rpage=n['realPage']
n['state']=1
n['virtualPage']=visit[i]
for z in vpage:
if z['virtualPage']==visit[i]:
z['realPage']=n['realPage']
z['state']=1
z['enterTime']=i+1
z['accessTime']=i+1
break
elif n==rpage[-1] and n['state']==1 and akind=='LRU':
print('no empty real pages!')
print('Their info in virtual talbe is:')
order_real=[]
mi=float('inf')
for k in range(rnum):
for z in vpage:
if z['realPage']==k:
order_real.append(z)
break;
print(z)
for j in order_real:
mi=min((j['accessTime'],mi))
for j in order_real:
if j['accessTime']==mi:
instead_rpage=j['realPage']
instead_vpage=j['virtualPage']
print('virtual page {} will be replaced!'
.format(instead_vpage))
print('real page {} will be filled with new virtual page!'
.format(instead_rpage))
for z in vpage:
if z['virtualPage']==instead_vpage:
z['state']=0
z['realPage']=-1
if z['virtualPage']==visit[i]:
z['state']=1
z['realPage']=instead_rpage
z['enterTime']=i+1
z['accessTime']=i+1
for m in rpage:
if m['virtualPage']==instead_vpage:
m['virtualPage']=visit[i]
elif n==rpage[-1] and n['state']==1 and akind=='FIFO':
print('no empty real pages!')
print('Their info in virtual talbe is:')
order_real=[]
mi=float('inf')
for k in range(rnum):
for z in vpage:
if z['realPage']==k:
order_real.append(z)
break;
print(z)
for j in order_real:
mi=min((j['enterTime'],mi))
for j in order_real:
if j['enterTime']==mi:
instead_rpage=j['realPage']
instead_vpage=j['virtualPage']
print('virtual page {} will be replaced!'
.format(instead_vpage))
print('real page {} will be filled with new virtual page!'
.format(instead_rpage))
for z in vpage:
if z['virtualPage']==instead_vpage:
z['state']=0
z['realPage']=-1
if z['virtualPage']==visit[i]:
z['state']=1
z['realPage']=instead_rpage
z['enterTime']=i+1
z['accessTime']=i+1
for m in rpage:
if m['virtualPage']==instead_vpage:
m['virtualPage']=visit[i]
print('virtual page {} is put into real page {}'
.format(visit[i],instead_rpage))
print('hit situation is: {}'.format(hit))
print('missing rate is:{}%'.format((vanum-len(hit))*100/vanum))
运行结果
说明:源码里我用的是random产生随机数,但为了方便各位对比结果,这里虚页访问地址流使用书上的数据,即我代码中注释的两行。
LRU
因运行结果较长,至此直接给出最后结果 :
FIFO
同样,至此直接给出最后数据结果:
最后,这是我第一次发文章,经验不足,请多指教!因为代码比较容易,就没有特地添加注释了,有什么问题可以评论讨论哦!