以下的內容均是親自問了操作系統老師問明白了才寫了這篇文章,如果有不對的地方歡迎指出錯誤。
採用頁式管理方案實施內存分配和回收。能夠處理以下的情形
⑴能夠輸入給定的內存頁面數,頁面大小,進程的個數及每個進程的頁數。
⑵當某進程提出申請空間的大小後,顯示能否滿足申請,以及爲該進程分配資源後內存空間的使用情況(被進程佔用的頁面,空閒的頁面);
⑶當某進程撤消時,顯示內存回收後內存空間的使用情況。
那怎麼去真真意義上的去理解這個實驗是怎麼做的呢?
按照步驟
(1)輸入頁的頁數。(假如爲5)
(2)輸入頁的大小。(假設爲1024 B)
下一步叫我們我們輸入進程的個數和頁數。(在這一步的時候大家應該會有疑問?怎麼輸入進程的個數以及頁數,輸入完之後—-當某進程提出申請空間的大小後,顯示能否滿足申請,以及爲該進程分配資源後內存空間的使用情況(被進程佔用的頁面,空閒的頁面))這又是怎麼理解的?
其實這個實驗具體應該是這樣做的。
現在我們假設進程數爲1(也就是隻考慮了單個進程的情況。)
那麼進程頁數是怎麼輸入的?
輸入進程的邏輯地址(假設爲883,1315,2456,1435,5678,3456,4352【單位都是B】)
基於頁表的大小爲1024B
用邏輯地址除以頁表的大小,商爲頁表號,餘數爲偏移地址。
例如以上的邏輯地址
883/1024=0—–餘數爲883
1315/1024=1—-餘數291
2456/1024=2—-餘數爲408
1435/1024=1—-餘數爲411
5678/1024=5—-餘數爲558【這裏需要注意的是這裏發生了越界中斷,why?因爲頁面的數爲5,意思就是商只能爲0,1,2,3,4,所以這裏發生了越界中斷,所以在這裏你需要提醒用戶這裏發生了越界中斷,發生越界中斷那麼這裏就跳入中斷處理程序,處理完中斷處理程序之後還要繼續對邏輯地址計算】
3456/1024=3—-餘數爲384
4352/1024=4—–餘數爲256
建立的表如下:
所以通過上面的表我們知道了這個進程的頁數爲6【數一下表格行數】
這樣也就回到了進程的頁數是怎麼輸入的啦!!!!
那麼這個進程對內存的訪問序列就是0,1,2,1,3,4
假設內存的物理塊爲3【】(why?如果仔細觀察的人會發現課本上一般都是3或者是4,對於這個物理塊的塊數必須在程序的開始之前指定我們假設爲3)
那麼假設我們採用FIFO置換算法
那麼就有了以下的替換情況的表格
所以就可以計算出淘汰頁號和缺頁率和缺頁次數!!!【這三個也是老師叫我們輸出的三個結果!!!】
所以總結下來,步驟如下:
(1)輸入頁的頁數。
(2)輸入頁的大小。
(3)輸入進程個數。(老師說可以只寫單線程,因爲考慮到多線程的時候還有回收比較難)
(4)輸入進程訪問的一系列邏輯地址。(可用一個數組存儲)
(5)基於頁的大小計算出訪問序列。
(6)基於物理塊的數量和三種算法得出訪問內存替換情況。
(7)基於(6)的步驟計算出淘汰頁號和缺頁率和缺頁次數和依次淘汰的頁號以及計算出物理地址並且輸出。
以下附上我的實驗源碼:採用python2.7寫的,然後按照分析的例題輸入數據:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Author : SundayCoder-俊勇
# @File : shijishiyan.py
import ast
print " 模擬設計存儲管理的分配與回收實踐說明"
str=raw_input("請輸入頁面的頁數和大小(例如:5(頁面頁數)1024(頁面大小,單位B)):")
FreeArea=str.split(" ")
# 內存物理塊的個數位爲3
Mblock=3
for i in range(0,len(FreeArea)):
if i<2:
if i%2==0:
print "頁數爲:"+FreeArea[i]+" 頁面大小爲:"+FreeArea[i+1]+"B"
# 得到頁的數量
pageNum=ast.literal_eval(FreeArea[i])
# 得到頁的大小
pageSize=ast.literal_eval(FreeArea[i+1])
else:
print "輸入有誤,請檢查輸入"
break
flag=True
while(flag):
Istrue=raw_input("申請進程內存分配請輸入1,結束程序請輸入2:")
if Istrue=="1":
strpro=raw_input("請輸入進程的訪問邏輯地址,單位爲B(例如883 1315 2456 1435 5678 3456 4352):")
pro=strpro.split(" ")
# 使用list來保存這個訪問邏輯地址與頁面大小之間的關係
list=[]
for i in range(0,len(pro)):
x=0
y=0
x=ast.literal_eval(pro[i])/pageSize
y=ast.literal_eval(pro[i])%pageSize
if x>=pageNum:
print "此處發生了越界中斷!!!越界中斷的進程邏輯位置爲"+pro[i]
print "處理越界中斷"
print "處理成功,返回中斷位置處繼續執行"
continue
else:
list.append(x)
list.append(y)
print list
print "進程擁有的頁數爲:"
print len(list)/2
print "進程的訪問序列爲:"
outlist=[]
for x in range(0,len(list)):
if x%2==0:
outlist.append(list[x])
print outlist
a = ["X"] * Mblock
# 採用一個list來記錄依次的缺頁號碼!!!
NumofLostpage=0
listOfLostPageNum=[]
print "採用FIFO置換算法替換頁面"
# FIFO的主要算法
# 記錄頁表信息
listpage=[]
dict2={}
#計算物理地址
out=[]
for i in range(0,len(list)):
if i%2==0:
if list[i] not in a:
NumofLostpage = NumofLostpage + 1
listpage.append(list[i])
listpage.append((NumofLostpage-1)%Mblock)
listOfLostPageNum.append(list[i])
# 滿了纔有依次淘汰頁面號。
if 'X' not in a:
out.append(a[(NumofLostpage-1)%Mblock])
a[(NumofLostpage-1)%Mblock]=list[i]
elif list[i] in a:
listpage.append(list[i])
listpage.append(a.index(list[i]))
print "缺頁次數是:"
print NumofLostpage
print "缺頁率是:"
print NumofLostpage/(len(list)/2.0)
print "依次缺頁號爲:"
print listOfLostPageNum
print "依次淘汰的頁面號是:"
print out
print "進程的邏輯地址轉化爲物理地址之後爲:"
# 用list記錄頁表後物理地址
wulilist=[]
print "頁表中的記錄如下:"
print listpage
for c in range(0,len(listpage)):
if c%2!=0:
wulilist.append(listpage[c]*pageSize+list[c])
print wulilist
elif Istrue=="2":
print "程序結束"
flag=False
else:
print "輸入有誤,程序結束"
flag=False
測試結果: