【操作系統】磁盤存儲空間的管理

實驗5 磁盤存儲空間的管理

一、實驗目的

??? 磁盤是用戶存放程序和數據的存儲設備,磁盤管理的主要目的是充分有效地利用磁盤空間。本實驗模擬實現磁盤空間的分配與回收,使學生對磁盤空間的管理有一個較深入的理解。

二、實驗內容

實驗任務:用位示圖管理磁盤空間實現磁盤塊的分配與回收

(1)假定現有一個磁盤組,共有8個柱面。每個柱面有4個磁道,每個磁道又劃分成4個物理盤塊。磁盤的空間使用情況用位示圖表示。位示圖用若干個字構成,每一位對應一個磁盤塊。“1”表示占用,“0”表示空閑。假定字長為16位,一個字可用來模擬磁盤的一個柱面,其位示圖如下圖所示。位示圖的初始狀態為第1個字為“1”,其他全部空閑。

字/位

0

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

0

1

1

1

1

1

1

1

1

1

1

1

1

1

1

1

1

1

0

0

0

0

0

0

0

0

0

0

0

0

0

0

0

0

2

…..

7

(2)為文件分配磁盤空間。首先輸入文件信息,主要包括文件名、文件大小等信息;然后根據位示圖為文件分配磁盤塊,磁盤塊可以不連續分配。要求輸出分配的磁盤塊的相對塊號和其絕對地址CHS(柱面號、磁頭號、扇區號),輸出位示圖。

(3)釋放文件所占的磁盤空間。輸入文件名,釋放其所占的磁盤空間。要求輸出該文件所分配的磁盤塊的相對塊號和其絕對地址CHS,輸出位示圖。

(4)根據用戶選擇輸出磁盤位示圖和磁盤中的所有文件信息。

三、測試用例

(0)初始磁盤位示圖和文件列表

(1)首先為3個以上的文件分配磁盤空間

設置f1、f2、f3三個文件,文件申請的磁盤空間大小分別為5KB、10KB、20KB。

【1】創建f1文件,文件大小為5KB。

【2】創建f2文件,文件大小為10KB。

【3】創建f3文件,大小為20KB。

(2)刪除先創建的一個文件

刪除f1文件。可以看到扇區16~扇區20已經被設置為0,表示未分配(空閑)扇區。

(3)為新的文件分配磁盤空間,容量大于剛剛刪除掉的那個文件

重新申請f1文件,文件大小為30KB。

(4)隨機刪除各個文件,看看磁盤空間的變化情況

【1】刪除f2文件

【2】刪除f3文件

【3】刪除f1文件

(5)所有的文件都刪除掉時,磁盤恢復為初始化狀態

如第(4)步中【3】刪除f1文件所示。

程序使用完畢后,退出系統。

四、實驗分析與總結

1)數據結構說明

【1】FCB的數據結構

??? FCB的代碼實現如下圖所示。

在本實驗中,利用struct構造FileInfo結構體,實現對文件基本信息的記錄,即文件控制塊。

該數據結構的基本變量包括:文件名字的字符串file_name、文件大小的整型單變量file_size、文件分配扇區的一維數組allocated_sectors。

【2】磁盤空間的數據結構

磁盤空間的代碼實現如下圖所示。

在本實驗中,利用struct構造StorageManager結構體,實現磁盤空間的初始化和管理。

該數據結構的基本變量包括:可用扇區總數的整型單變量available_sectors、磁盤位示圖的二維數組bitmap、文件映射的哈希表files。

該數據結構的功能包括:構造磁盤空間函數createFile、創建文件(給文件分配磁盤空間)函數createFile、顯示磁盤存儲狀態函數displayStatus、顯示磁盤中的文件序列函數fileDetails、刪除文件(回收給文件分配的磁盤空間)函數deleteFile。

2)程序流程圖

【1】主函數的程序流程圖

主要代碼段:

對應流程圖:

【2】構造磁盤空間函數的程序流程圖

【3】創建文件(給文件分配磁盤空間)函數的程序流程圖

【4】顯示磁盤存儲狀態函數的程序流程圖

【5】顯示磁盤中的文件序列函數的程序流程圖

【6】刪除文件(回收給文件分配的磁盤空間)函數的程序流程圖

【7】菜單函數的程序流程圖

3)程序運行結果,打印程序運行時的初值和運行結果

如【三、測試用例】中所示。測試的流程圖如下圖所示。

4)實驗知識點總結和實驗收獲與體會

1:加深了對磁盤存儲空間管理的理解,將抽象的概念應用到實際情況中。位示圖演示了如何有效地管理資源,特別是在多個文件競爭相同磁盤塊的情況下。實際磁盤操作的各步驟內容如下所示。

步驟

具體內容

步驟1:初始化位示圖

初始化一個位示圖來表示磁盤空間的占用情況。

使用16位字來表示一個柱面的狀態,初始狀態為第一個字為"1",其余全部為"0",表示柱面1被占用,其余柱面為空閑。

步驟2:文件分配磁盤空間

用戶輸入文件信息,包括文件名和文件大小。

根據位示圖為文件分配磁盤塊,可以不連續分配。這意味著文件的數據塊可以分散在磁盤上。

輸出分配的磁盤塊的相對塊號和其絕對地址CHS(柱面號、磁頭號、扇區號)。

更新位示圖以反映已分配的磁盤塊狀態。

步驟3:釋放文件所占的磁盤空間

用戶輸入要釋放的文件名。

根據文件名查找該文件所占用的磁盤塊。

輸出被釋放的磁盤塊的相對塊號和其絕對地址CHS。

更新位示圖以反映已釋放的磁盤塊狀態。

步驟4:輸出磁盤位示圖和文件信息

用戶可以選擇輸出磁盤位示圖,以查看磁盤空間的占用情況。

用戶還可以選擇輸出磁盤中的所有文件信息,包括文件名、大小和存儲位置等信息。

2:位示圖法是磁盤空間管理方法的其中一個,用于盤塊的分配、回收,并且涉及絕對地址與邏輯盤塊之間的轉換。磁盤上的所有盤塊都有一個bit與之對應,由所有盤塊所對應的位構成一個集合,稱為位示圖。位示圖主要是由二維數組表示的,其中行號稱為字號,列號稱為位號。位示圖的示例圖如下所示。

3:磁盤塊是存儲介質上連續扇區所組成的一個區域,也被稱作物理塊、簇。磁盤塊的重要性如下:①讀取方便:由于扇區的存儲數量比較小,所以OS將相鄰的扇區組合在一起,形成一

個塊,再對塊進行整體的操作。②分離對底層的依賴:OS忽略對底層物理存儲結構的設計。通過虛擬出來磁盤塊的概念,在系統中認為塊是最小的單位。

4:塊是主存和輔助進行信息交換的最小單位,每次總是交換一塊或整數塊信息。

5:磁盤的物理地址CHS由柱面(Cylinder)、磁頭(Head)、扇區(Sector)構成。磁盤的物理結構如下圖所示。

6:在邏輯盤塊地址LBA與物理地址CHS的轉換中,假設磁頭數是n,每個磁道的扇區數是m,則柱面號、磁頭號、扇區號的計算公式如下所示。

目標計算量

計算公式

柱面號C

C = LBA / (n * m)

磁頭號H

H = (LBA / m) % n

扇區號S

S = (LBA % m)

7:磁盤管理的其他方法包括:空閑表法(主要用于交換區管理,可采用的分配算法有首次適應算法和最佳適應算法)、空閑鏈法(FAT系統采用,包括空閑盤塊鏈和空閑盤區鏈)、成組鏈接法(Linux系統采用,采用了空閑表和鏈表進行結合)。

6)實驗源代碼

#include <iostream>

#include <vector>

#include <unordered_map>

using namespace std;

// 文件信息結構體(FCB,file control block)

struct FileInfo { ?

? ? string file_name; ? ? ? ? ? ? ? // 文件名字

? ? int file_size; ? ? ? ? ? ? ? ? ?// 文件大小

? ? vector<int> allocated_sectors; ?// 文件分配的扇區

};

// 存儲管理器結構體(磁盤管理)

struct StorageManager { ? ? ? ? ? ? ? ? ? ?

? ? int available_sectors; ? ? ? ? ? ? ? ? ?// 可用扇區總數

? ? vector<vector<int>> bitmap; ? ? ? ? ? ? // 磁盤位圖

? ? unordered_map<string, FileInfo> files; ?// 文件映射

? ? StorageManager(); ? ? ? ? ? ? ? ? ? ? ? // 構造函數

? ? bool createFile(const string&, int); ? ?// 創建文件

? ? void displayStatus(); ? ? ? ? ? ? ? ? ? // 顯示存儲狀態

? ? void fileDetails(const FileInfo&); ? ? ?// 顯示文件詳情

? ? bool deleteFile(const string&); ? ? ? ? // 刪除文件

};

// 構造函數

// 假定現有一個磁盤組,共有8個柱面。每個柱面有4個磁道,每個磁道又劃分成4個物理盤塊。

StorageManager::StorageManager() : available_sectors(128) {

? ? bitmap.resize(8, vector<int>(16, 0)); ? // 構造8*16個空盤塊

? ? for (int j = 0; j < 16; ++j) {

? ? ? ? bitmap[0][j] = 1; ?// 預留第一行作為系統文件,該柱面不可用

? ? ? ? // 位示圖的初始狀態為第1個字為“1”,其他全部空閑。

? ? }

}

// 創建文件函數

bool StorageManager::createFile(const string& name, int size) {

? ? if (files.find(name) != files.end()) { ?// 如果文件名字不在末尾,則沖突

? ? ? ? cout << "錯誤: 文件已存在。"<< endl;

? ? ? ? return false;

? ? } ?

? ? if (size > available_sectors) { ? ? // 如果文件大小大于空閑扇區大小

? ? ? ? cout << "錯誤: 空間不足。"<< endl;

? ? ? ? return false;

? ? }

? ?

? ? // 創建新文件的FCB

? ? FileInfo newFile{ name, size, {} };

? ?

? ? // 更新位示圖中信息

? ? for (int i = 0; i < bitmap.size() && size > 0; ++i) {

? ? ? ? for (int j = 0; j < bitmap[i].size() && size > 0; ++j) {

? ? ? ? ? ? if (bitmap[i][j] == 0) { ? ?// 如果這個盤塊為空

? ? ? ? ? ? ? ? bitmap[i][j] = 1; ? // 設置為已經分配

? ? ? ? ? ? ? ? newFile.allocated_sectors.push_back(i * 16 + j); ? ?// 分配區增加這個盤塊

? ? ? ? ? ? ? ? --size; ? ? // 空閑區大小-=1

? ? ? ? ? ? ? ? --available_sectors; ? ?// 同上

? ? ? ? ? ? }

? ? ? ? }

? ? }

? ? files[name] = newFile; ?// hash表設置

? ? fileDetails(newFile); ? // 顯示新建文件詳情

? ? return true;

}

// 顯示磁盤分配情況函數

void StorageManager::displayStatus() {

? ? cout << "磁盤位圖:" << endl;

? ? for (int i = 0; i < bitmap.size(); ++i) {

? ? ? ? for (int j = 0; j < bitmap[i].size(); ++j) {

? ? ? ? ? ? cout << bitmap[i][j] << ' ';

? ? ? ? }

? ? ? ? cout << endl; ? // 換行顯示

? ? }

? ?

? ? cout << endl << "文件列表:" << endl;

? ? for (const auto& pair : files) {

? ? ? ? cout << pair.first << "\t大小: " << pair.second.file_size << endl;

? ? }

? ? cout << endl;

}

// 顯示文件內存詳情函數

void StorageManager::fileDetails(const FileInfo& file) {

? ? cout << "文件 '" << file.file_name << "' 的詳細信息:"<< endl;

? ? for (int sector : file.allocated_sectors) {

? ? ? ? cout << "扇區: " << sector << ";"; ? ?//遍歷扇區

? ? }

? ? cout << endl;

}

// 刪除文件函數

bool StorageManager::deleteFile(const string& name) {

? ? auto it = files.find(name);

? ? if (it == files.end()) {

? ? ? ? cout << "錯誤: 文件不存在。"<< endl;

? ? ? ? return false;

? ? }

? ? for (int sector : it->second.allocated_sectors) {

? ? ? ? int i = sector / 16;

? ? ? ? int j = sector % 16;

? ? ? ? bitmap[i][j] = 0;

? ? ? ? ++available_sectors;

? ? }

? ? files.erase(it);

? ? cout << "文件 '" << name << "' 已刪除。"<< endl;

? ? return true;

}

// 菜單函數

void menu(StorageManager manager){

? ? manager.displayStatus();

? ? cout << "根據數字提示選擇操作: ";

? ? cout << endl << "1:創建文件, 2:刪除文件, 3:退出系統"<< endl;

}

// 主函數

int main() {

? ? StorageManager manager;

? ? int action;

? ? string filename;

? ? int filesize;

? ? while (true) {

? ? ? ? cout << endl;

? ? ? ? menu(manager);

? ? ? ? cin >> action;

? ? ? ? switch (action) {

? ? ? ? ? ? case 1:

? ? ? ? ? ? ? ? cout << "輸入文件名: ";

? ? ? ? ? ? ? ? cin >> filename;

? ? ? ? ? ? ? ? cout << "輸入文件大小: ";

? ? ? ? ? ? ? ? cin >> filesize;

? ? ? ? ? ? ? ? if (manager.createFile(filename, filesize)) {

? ? ? ? ? ? ? ? ? ? cout << "文件創建成功。\n";

? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? ? break;

? ? ? ? ? ? case 2:

? ? ? ? ? ? ? ? cout << "輸入要刪除的文件名: ";

? ? ? ? ? ? ? ? cin >> filename;

? ? ? ? ? ? ? ? if (manager.deleteFile(filename)) {

? ? ? ? ? ? ? ? ? ? cout << "文件刪除成功。\n";

? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? ? break;

? ? ? ? ? ? case 3:

? ? ? ? ? ? ? ? cout << "程序退出。\n";

? ? ? ? ? ? ? ? return 0;

? ? ? ? ? ? default:

? ? ? ? ? ? ? ? cout << "無效的操作。\n";

? ? ? ? }

? ? }

? ? return 0;

}

/*

測試用例:

【創建文件】

1

f1

5

?

1

f2

10

1

f3

20

【刪除f1】

2

f1

【重新創建更大的f1】

1

f1

10

【隨機刪除】

2

f2

2

f3

2

f1

【結束】

*/

五、實驗指導

(1)程序主框架和數據結構

程序主框架可參考內存管理實驗,功能主要包括:分配空間、回收空間、打印位示圖、打印文件信息等。

數據結構主要包括:

位示圖:保存磁盤分配情況;

文件基本信息表:包括文件名、文件長度、創建時間、文件分配的相對磁盤號等。

2)申請和釋放磁盤塊操作

申請一個磁盤塊時,由磁盤管理程序檢查位示圖,找出一個為0的位,計算磁盤的物理地址,即求出它的柱面號、磁道號和扇區號。

釋放一個相對物理塊時,磁盤管理程序計算該塊在位示圖中的位置,再把相應由“1”改為“0”。由相對塊號計算字號和位號。

3)磁盤空間分配和回收流程圖

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/697481.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/697481.shtml
英文地址,請注明出處:http://en.pswp.cn/news/697481.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

FreeSWITCH debian11/12 apt安裝

官方給的easy way安裝方式如下&#xff1a; # 換成自己的token TOKENpat_ZrPXJQ8JNWsVQW2ubhnUwi7gapt-get update && apt-get install -y gnupg2 wget lsb-releasewget --http-usersignalwire --http-password$TOKEN -O /usr/share/keyrings/signalwire-freeswitch-…

#LLM入門|Prompt#1.2_提示原則_Guidelines

提示原則 一、編寫清晰、具體的指令 使用分隔符清晰地表示輸入的不同部分&#xff1a; 在Prompt中使用分隔符&#xff0c;如、“”"、< >、 、:等&#xff0c;將不同的文本部分區分開來&#xff0c;避免混淆和意外的結果。分隔符能夠防止提示詞注入&#xff0c;提…

petalinux_zynq7 驅動DAC以及ADC模塊之四:python實現http_api

前文&#xff1a; petalinux_zynq7 C語言驅動DAC以及ADC模塊之一&#xff1a;建立IPhttps://blog.csdn.net/qq_27158179/article/details/136234296petalinux_zynq7 C語言驅動DAC以及ADC模塊之二&#xff1a;petalinuxhttps://blog.csdn.net/qq_27158179/article/details/1362…

Java觀察者模式:實現高效的事件驅動編程

Java中的裝飾者模式&#xff1a;靈活地為對象添加功能 一、引言 在軟件設計中&#xff0c;我們經常需要為對象動態地添加功能或行為。裝飾者模式&#xff08;Decorator Pattern&#xff09;是一種結構型設計模式&#xff0c;它允許我們在運行時將功能動態地添加到對象上&…

串的相關題目

于是他錯誤的點名開始了 我發現有關hash得題目有些是可以通過map數組來完成的&#xff1a;何為map數組&#xff0c;我們先思考一下最簡單的桶的排序&#xff0c;桶排序是將我們需要數字最為下標輸進數組中&#xff0c;而數組是存放的數字是這個數字出現的次數&#xff0c;但是由…

Matlab論文插圖繪制模板第137期—極坐標分組氣泡圖

在之前的文章中&#xff0c;分享了Matlab極坐標氣泡圖的繪制模板&#xff1a; 進一步&#xff0c;再來分享一下極坐標分組氣泡圖。 先來看一下成品效果&#xff1a; ? 特別提示&#xff1a;本期內容『數據代碼』已上傳資源群中&#xff0c;加群的朋友請自行下載。有需要的朋…

解決SSH遠程登錄開飯板出現密碼錯誤問題

輸入“adduser Zhanggong回車”&#xff0c;使用adduser命令創建開發板用戶名為Zhanggong 輸入密碼“123456” 輸入密碼“123456”

openGauss學習筆記-226 openGauss性能調優-系統調優-配置LLVM-LLVM適用場景與限制

文章目錄 openGauss學習筆記-226 openGauss性能調優-系統調優-配置LLVM-LLVM適用場景與限制226.1 適用場景226.2 非適用場景 openGauss學習筆記-226 openGauss性能調優-系統調優-配置LLVM-LLVM適用場景與限制 226.1 適用場景 支持LLVM的表達式 查詢語句中存在以下的表達式支持…

PostgreSQL數據庫備份和恢復

一、數據庫備份 /usr/lib/postgresql/16/bin/pg_dump -h localhost -p 5432 -U odoo -F c -b -v -f backup.sql laonian 二、數據庫恢復 1 現在目標pgsql數據庫中創建空數據庫老年 create database laonian owner odoo; 2 執行恢復命令&#xff08;windows系統下&#xff…

網絡安全-nc(Netcat)工具詳解

經常在反彈shell的時候使用nc命令&#xff0c;但是從來沒有了解過&#xff0c;今天翻書看到了&#xff0c;準備記錄一下。 nc全稱Netcat&#xff0c;是TCP/IP連接的瑞士軍刀。哈哈我最喜歡瑞士軍刀了。 有一個比較偏的知識點&#xff0c;nc還可以探測目標的端口是否開放&…

Modern C++ std::variant的5個特性+原理

1 前言 上一節《Modern C std::variant的實現原理》我們簡單分析了std::variant的實現原理&#xff0c;其實要學好C編程&#xff0c;除了看優秀的代碼包括標準庫實現&#xff0c;讀文檔也是很便捷且必須的一種辦法。 本節我將逐條解析文檔中的五個特性&#xff0c;解析的辦法有…

LINUX操作系統:重定向

輸出重定向&#xff1a;將命令行程序的輸出重定向到其他位置&#xff0c;如文件、程序、打印機等。 輸入重定向&#xff1a;從其他位置獲取輸入&#xff0c;而不是從標準輸入&#xff08;鍵盤、鼠標等&#xff09; 錯誤重定向&#xff1a;同輸出。 輸出重定向&#xff08;Outp…

R語言【sp】——over(),%over%

Package sp version 1.5-0 Description 點、網格和多邊形的一致空間覆蓋:在對象x的空間位置從空間對象y檢索索引或屬性。 Usage over(x, y, returnList = FALSE, fn = NULL, ...) x %over% y Arguments 參數【x】:查詢的幾何(位置)。 參數【y】:層,從中查詢幾何或屬性。…

PYTHON-使用正則表達式進行模式匹配

目錄 Python 正則表達式Finding Patterns of Text Without Regular ExpressionsFinding Patterns of Text with Regular ExpressionsCreating Regex ObjectsMatching Regex ObjectsReview of Regular Expression MatchingMore Pattern Matching with Regular ExpressionsGroupi…

阿里開源低代碼引擎 - Low-Code Engine

阿里開源低代碼引擎 - Low-Code Engine 本文主要介紹如何在Windows運行/開發阿里開源低代碼引擎 - Low-Code Engine 詳細文檔參見【 阿里開源低代碼引擎 - Low-Code Engine 官方文檔】 目錄 阿里開源低代碼引擎 - Low-Code Engine一、環境準備1、使用 WSL 在 Windows 上安裝 L…

方法鑒權:基于 Spring Aop 的注解鑒權

在Spring框架中&#xff0c;可以使用面向切面編程&#xff08;AOP&#xff09;來實現注解鑒權。這通常涉及到定義一個切面&#xff08;Aspect&#xff09;&#xff0c;該切面會在方法執行前進行攔截&#xff0c;并根據注解value值來決定是否允許執行該方法。 簡單思路&#xf…

Java學習筆記2024/2/22

面向對象進階部分學習方法&#xff1a; 特點&#xff1a; 邏輯性沒有那么強&#xff0c;但是概念會比較多。 記憶部分重要的概念&#xff0c;理解課堂上講解的需要大家掌握的概念&#xff0c;多多練習代碼。 今日內容 復習回顧 static關鍵字 繼承 教學目標 能夠掌握st…

【開源】JAVA+Vue.js實現醫院門診預約掛號系統

目錄 一、摘要1.1 項目介紹1.2 項目錄屏 二、功能模塊2.1 功能性需求2.1.1 數據中心模塊2.1.2 科室醫生檔案模塊2.1.3 預約掛號模塊2.1.4 醫院時政模塊 2.2 可行性分析2.2.1 可靠性2.2.2 易用性2.2.3 維護性 三、數據庫設計3.1 用戶表3.2 科室檔案表3.3 醫生檔案表3.4 醫生放號…

qml 保存當前界面并在其圖片中添加文字

使用場景&#xff1a;在保存二維碼的時候&#xff0c; 在二維碼圖片加標題或描述 保存后的圖片 demo&#xff1a;https://download.csdn.net/download/uVarAndMethod/88868455

Electron實戰之環境搭建

工欲善其事必先利其器&#xff0c;在進行實戰開發的時候&#xff0c;我們最終的步驟是搞好一個舒服的開發環境&#xff0c;目前支持 Vue 的 Electron 工程化工具主要有 electron-vue、Vue CLI Plugin Electron Builder、electron-vite。 接下來我們將分別介紹基于 Vue CLI Plu…