【操作系统】磁盘存储空间的管理

实验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.mzph.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…