操作系统 实验3【动态分区存储管理】
目錄
一、實驗目的(目的與任務)
二、實驗內容(內容、要求與安排方式)
三、實驗代碼
①創建表示分區的類,類包含:分區ID、起始地址、結束地址、分區長度、分區狀態
②導入python模塊,方便拷貝分區對象
③編寫表示分區狀態的函數
④編寫冒泡排序函數
⑤編寫首次適應算法(First Fit)函數
⑥編寫最佳適應算法(Best Fit)函數
⑦回收內存(作業)函數
⑧編寫主函數
完整實驗代碼
四、實驗結果
五、實驗總結
一、實驗目的(目的與任務)
熟悉并掌握動態分區分配的各種算法。
熟悉并掌握動態分區中分區回收的各種情況,并能夠實現分區合并。
二、實驗內容(內容、要求與安排方式)
用高級語言模擬實現動態分區存儲管理,要求:
? ? ? (2)作業不能同名,但是刪除后可以再用這個名字;
? ? ? (3)作業空間回收是輸入作業名,回收相應的空間,如果這個作業名不存在,也要有相應的提示。
三、實驗代碼
①創建表示分區的類,類包含:分區ID、起始地址、結束地址、分區長度、分區狀態
class?Memory(object):
????def?__init__(self,?start,?end,?length,?state=1,?ID=0):
????????self.Id?=?ID??##ID為0是未分配,其余為任務編號
????????self.start?=?start
????????self.end?=?end
????????self.length?=?length
????????self.state?=?state??#?state為1:內存未分配
②導入python模塊,方便拷貝分區對象
import?copy?#?導入python模塊,copy僅拷貝對象本身
③編寫表示分區狀態的函數
def?show_memory(list):
????print("分配狀態????分區號????起始地址???終止地址??分區大小")
????for?i?in?range(0,?len(list)):
????????p?=?list[i]
????????if?p.state?==?1:
????????????print("%s%s%s%11.d%11.d%10.d"?%?('空閑',?"??????????",?p.Id,?p.start,?p.end,?p.length))
????????else:
????????????print("%s%s%s%11.d%11.d%10.d"?%?('已分配',?"????????",?p.Id,?p.start,?p.end,?p.length))
④編寫冒泡排序函數
##冒泡排序
def?bubble_sort(list):
????count?=?len(list)
????for?i?in?range(0,?count):
????????for?j?in?range(i?+?1,?count):
????????????if?list[i].length?<?list[j].length:
????????????????list[i],?list[j]?=?list[j],?list[i]
????return?list
⑤編寫首次適應算法(First Fit)函數
#?首次適應算法(First?Fit)
def?FF(work_id,?work_length,?list):
????for?i?in?list:
????????if?i.Id?==?work_id:
????????????print('作業已存在!')
????????????return
????for?i?in?range(0,?len(list)):
????????p?=?list[i]
????????if?p.state?==?1?and?p.length?>?work_length:??#?p是當前未分配內存的大小
????????????node2?=?Memory(p.start?+?work_length,?p.end,?p.length?-?work_length,?1,?0)??#?剩下的未分配的
????????????a?=?Memory(p.start,?p.start?+?work_length?-?1,?work_length,?state=0,?ID=work_id)??#?a是已分配的
????????????del?list[i]
????????????list.insert(i,?node2)
????????????list.insert(i,?a)
????????????show_memory(list)
????????????return
????????if?p.state?==?1?and?p.length?==?work_length:
????????????p.state?=?0
????????????show_memory(list)
????????????return
????print("內存空間不足!")
⑥編寫最佳適應算法(Best Fit)函數
##最佳適應算法(Best?Fit)
def?BF(work_id,?work_length,?li):
????for?i?in?li:
????????if?i.Id?==?work_id:
????????????print('作業已存在!')
????????????return
????q?=?copy.copy(li)
????q?=?bubble_sort(q)??#?從小到大排序,給所有已分配和未分配的排序
????s?=?-1
????ss12?=?-1
????for?i?in?range(0,?len(q)):
????????p?=?q[i]
????????if?p.state?==?1?and?p.length?>?work_length:??#?p.state?==?1?已分配的不參與分配
????????????s?=?p.start??#?s得到起始位置
????????elif?p.state?==?1?and?p.length?==?work_length:
????????????ss12?=?p.start
????if?s?==?-1?and?ss12?==?-1:
????????print("內存空間不足!")
????????return
????for?i?in?range(0,?len(li)):
????????p?=?li[i]
????????if?p.start?==?s:
????????????node2?=?Memory(p.start?+?work_length,?p.end,?p.length?-?work_length,?1,?0)??#?未分配
????????????a?=?Memory(p.start,?p.start?+?work_length?-?1,?work_length,?state=0,?ID=work_id)
????????????del?li[i]
????????????li.insert(i,?node2)
????????????li.insert(i,?a)
????????????show_memory(li)
????????????return
????????elif?p.start?==?ss12:
????????????p.state?=?0
????????????show_memory(li)
????????????return
?
⑦回收內存(作業)函數
##回收內存(作業)函數
def?free1(work_id,?li):
????for?i?in?range(0,?len(li)):
????????p?=?li[i]
????????if?p.Id?==?work_id:
????????????p.state?=?1
????????????target?=?i
????????????p.Id?=?0
????????????break
????#?向前合并空閑塊
????if?target?-?1?>?0:
????????if?li[target?-?1].state?==?1:
????????????a?=?Memory(li[target?-?1].start,?li[target].end,?li[target?-?1].length?+?li[target].length,?1,?0)
????????????del?li[target?-?1]
????????????del?li[target?-?1]
????????????li.insert(target?-?1,?a)
????????????target?=?target?-?1
????#?向后合并空閑塊
????if?target?+?1?<?len(li):
????????if?li[target?+?1].state?==?1:
????????????a?=?Memory(li[target].start,?li[target?+?1].end,?li[target].length?+?li[target?+?1].length,?1,?0)
????????????del?li[target]
????????????del?li[target]
????????????li.insert(target,?a)
????show_memory(li)
⑧編寫主函數
if?__name__?==?'__main__':
????print("輸入內存大小:")
????size?=?int(input())
????a?=?Memory(0,?size?-?1,?size,?state=1,?ID=0)
????b?=?[]
????b.append(a)
????print('*******1:初始化******')
????print('*******2:分配空間****')
????print('*******3:回收********')
????print('*******4:查看********')
????print('*******5:退出********')
????while?(True):
????????select?=?input('請輸入想要執行的功能:')
????????if?select?==?'5':
????????????break
????????elif?select?==?'1':
????????????print("輸入內存大小:")
????????????size?=?int(input())
????????????a?=?Memory(0,?size?-?1,?size,?state=1,?ID=0)
????????????b?=?[]
????????????b.append(a)
????????elif?select?==?'2':
????????????print("1.首次適應算法:FF")
????????????print("2.最佳適應算法:BF")
????????????x?=?input("請輸入分配執行的算法:")
????????????x?=?float(x)
????????????repit?=?'Y'
????????????while?(repit?==?'Y'):
????????????????if?x?==?1:
????????????????????work_size?=?input('請輸入作業id和大小:').split()
????????????????????FF(work_size[0],?int(work_size[1]),?b)
????????????????????repit?=?input('是否繼續(Y/N):')
????????????????elif?x?==?2:
????????????????????work_size?=?input('請輸入作業id和大小:').split()
????????????????????BF(work_size[0],?int(work_size[1]),?b)
????????????????????repit?=?input('是否繼續(Y/N):')
????????elif?select?==?'3':
????????????id_delete?=?input('請輸入刪除作業id:')
????????????free1(id_delete,?b)
????????else:
????????????show_memory(b)
完整實驗代碼
import copy # 導入python模塊,copy僅拷貝對象本身# 創建表示分區的類,類包含:分區ID、起始地址、結束地址、分區長度、分區狀態 class Memory(object):def __init__(self, start, end, length, state=1, ID=0): # __init__()方法是一種特殊的方法,被稱為類的初始化方法,當創建這個類的實例時就會調用該方法# self代表類的實例,self在定義類的方法時是必須有的,雖然在調用時不必傳入相應的參數self.Id = ID ##ID為0是未分配,其余為任務編號self.start = startself.end = endself.length = lengthself.state = state # state為1:內存未分配# 編寫表示分區狀態的函數 def show_memory(list):print("分配狀態 分區號 起始地址 終止地址 分區大小")for i in range(0, len(list)):p = list[i]if p.state == 1:print("%s%s%s%11.d%11.d%10.d" % ('空閑', " ", p.Id, p.start, p.end, p.length))else:print("%s%s%s%11.d%11.d%10.d" % ('已分配', " ", p.Id, p.start, p.end, p.length))# 首次適應算法(First Fit) def FF(work_id, work_length, list):for i in list:if i.Id == work_id:print('作業已存在!')returnfor i in range(0, len(list)):p = list[i]if p.state == 1 and p.length > work_length: # p是當前未分配內存的大小node2 = Memory(p.start + work_length, p.end, p.length - work_length, 1, 0) # 剩下的未分配的a = Memory(p.start, p.start + work_length - 1, work_length, state=0, ID=work_id) # a是已分配的del list[i]list.insert(i, node2)list.insert(i, a)show_memory(list)returnif p.state == 1 and p.length == work_length:p.state = 0show_memory(list)returnprint("內存空間不足!")# 回收內存(作業)函數 def free1(work_id, li):for i in range(0, len(li)):p = li[i]if p.Id == work_id:p.state = 1target = ip.Id = 0break# 向前合并空閑塊if target - 1 > 0:if li[target - 1].state == 1:a = Memory(li[target - 1].start, li[target].end, li[target - 1].length + li[target].length, 1, 0)del li[target - 1]del li[target - 1]li.insert(target - 1, a)target = target - 1# 向后合并空閑塊if target + 1 < len(li):if li[target + 1].state == 1:a = Memory(li[target].start, li[target + 1].end, li[target].length + li[target + 1].length, 1, 0)del li[target]del li[target]li.insert(target, a)show_memory(li)# 冒泡排序 def bubble_sort(list):count = len(list)for i in range(0, count):for j in range(i + 1, count):if list[i].length < list[j].length:list[i], list[j] = list[j], list[i]return list# 最佳適應算法(Best Fit) def BF(work_id, work_length, li):for i in li:if i.Id == work_id:print('作業已存在!')returnq = copy.copy(li)q = bubble_sort(q) # 從小到大排序,給所有已分配和未分配的排序s = -1ss12 = -1for i in range(0, len(q)):p = q[i]if p.state == 1 and p.length > work_length: # p.state == 1,已分配的不參與分配s = p.start # s得到起始位置elif p.state == 1 and p.length == work_length:ss12 = p.startif s == -1 and ss12 == -1:print("內存空間不足!")returnfor i in range(0, len(li)):p = li[i]if p.start == s:node2 = Memory(p.start + work_length, p.end, p.length - work_length, 1, 0) # 未分配a = Memory(p.start, p.start + work_length - 1, work_length, state=0, ID=work_id)del li[i]li.insert(i, node2)li.insert(i, a)show_memory(li)returnelif p.start == ss12:p.state = 0show_memory(li)return# 主函數 if __name__ == '__main__':print("輸入內存大小:")size = int(input())a = Memory(0, size - 1, size, state=1, ID=0)b = []b.append(a)print('*******1:初始化******')print('*******2:分配空間(FF\BF)****')print('*******3:回收********')print('*******4:查看********')print('*******5:退出********')while (True):select = input('請輸入想要執行的功能:')if select == '5':breakelif select == '1':print("輸入內存大小:")size = int(input())a = Memory(0, size - 1, size, state=1, ID=0)b = []b.append(a)elif select == '2':print("1.首次適應算法:FF")print("2.最佳適應算法:BF")x = input("請輸入分配執行的算法:")x = float(x)repit = 'Y'while (repit == 'Y'):if x == 1:work_size = input('請輸入作業id和大小:').split()FF(work_size[0], int(work_size[1]), b)repit = input('是否繼續(Y/N):')elif x == 2:work_size = input('請輸入作業id和大小:').split()BF(work_size[0], int(work_size[1]), b)repit = input('是否繼續(Y/N):')elif select == '3':id_delete = input('請輸入刪除作業id:')free1(id_delete, b)else:show_memory(b)四、實驗結果
BF算法有一點小毛病兒:兩個相同的分區,比如2個20,這個BF是從末尾地址開始分配的;不能這樣寫,應該從低地址開始分配。
? ?
五、實驗總結
動態分區分配算法包括如下4種算法:首次適應算法(First Fit)、最佳適應算法(Best Fit)、最壞適應算法(Worst Fit)、臨近適應算法(Next Fit)。
動態分區管理方式,在初始時不將主存劃分區域,而是把占用區域外的空間看作一個大的空閑區。當作業要求裝入主存時,根據作業的大小查詢主存內各空閑區的狀態,按照特定的算法選擇一個合適的空閑區,按作業大小劃分出一個分區并裝入該作業,剩下的區域作為新的空閑區。
當作業執行完畢后,所占用的主存空間將被回收,成為一個空閑區;如果該空閑區的相鄰分區也是空閑區,則需要將相鄰空閑區合并成一個空閑區。
?? 通過本次實驗,我對動態分區分配算法有了更深的理解,將4種算法的特點整理如下:
| 算法 | 算法思想 | 分區排列順序 | 優點 | 缺點 |
| 首次適應算法 | 從頭到尾尋找合適的分區 | 空閑分區以地址遞增次序排列 | 綜合看,首次適應算法性能最好。算法開銷小,回收分區后,一般不需要對空閑分區隊列重新排序 | 略! |
| 最佳適應算法 | 優先使用更小的分區,以保留更多的大分區 | 空閑分區以容量遞增次序排列 | 會有更多的大分區被保留下來,更能滿足大進程需求 | 會產生很多太小的、難以利用的碎片:算法開銷大,回收分區后可能需要對空閑分區隊列重新排序 |
| 最壞適應算法 | 優先使用更大的分區,以防止產生太小的不可用碎片 | 空閑分區以容量遞減次序排列 | 可以減少難以利用的小碎片 | 大分區容易被用完,不利于大進程:算法開銷大(原因同上) |
| 臨近適應算法 | 由首次適應算法演變而來,每次從上次查找結束的位置開始查找 | 空閑分區以地址遞增次序排列(可排列成循環鏈表) | 不用每次都從低地址的小分區開始檢索。算法開銷小(原因同首次適應算法) | 會使高地址的大分區也被用完 |
總結
以上是生活随笔為你收集整理的操作系统 实验3【动态分区存储管理】的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Python常见的数据类型【数字、布尔、
- 下一篇: java信息管理系统总结_java实现科