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

实验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://xiahunao.cn/news/2803426.html

如若内容造成侵权/违法违规/事实不符,请联系瞎胡闹网进行投诉反馈,一经查实,立即删除!

相关文章

Canal + Kafka 同步 MySQL 数据到 Redis

解决缓存和数据库一致性问题 一般来说&#xff0c;缓存中的数据没什么问题&#xff0c;但是数据库更新后&#xff0c;就容易出现缓存&#xff08;Redis&#xff09;和数据库&#xff08;MySQL&#xff09;间的数据一致性问题。由于写和读是并发的&#xff0c;没法保证顺序&…

运营抖店为什么不能多选类目?什么类目适合新手来玩?

大家好&#xff0c;我是电商小布。 想要入驻抖音小店&#xff0c;必备的资质材料就是营业执照。 而执照上的范围&#xff0c;就是我们开店所能选择的经营类目。 有的小伙伴在开店的时候&#xff0c;并没有想明白自己是想要做什么&#xff0c;小店未来的发展方向是什么。 结…

Docker基础篇(四) 容器数据卷 容器间传递共享(--volumes-from)

容器间传递共享 当前没有运行的容器 两个数据卷&#xff1a; containVolum-01 containVolum-02 docker run -it --name zenA zen/centos 上面生成了容器 zenA ctrl P Q docker run -it --name zenB1 --volumes-from zenA zen/centos ctrl P Q docker run -it --name zen…

全球游戏市场回暖,Flat Ads推动海外获客增长

摘要:热门游戏品类分析,解读新兴市场与赛道 近日,中国音数协游戏工委发布了《2023年中国游戏出海研究报告》,据报告数据显示,2023年,全球游戏市场规模11773.79亿元,同比增长6.00%,呈现增长回暖趋势。 图源:伽马数据 1.SLG和RPG游戏热度居高不下,休闲游戏增长势头强劲 目前,S…

java 时间格式 YYYY 于yyyy的区别

java formatDate 时间时&#xff0c;经常需要输入格式比如 YYYYMMDD,yyyyMMdd 这两个是有区别的 具体每个参数可以看下面

左手“兑抵接”,右手债务逾期,华夏幸福离“上岸”还有多远?

撰稿|行星 来源|贝多财经 进入2024年&#xff0c;华夏幸福仍不太“幸福”。 近日&#xff0c;华夏幸福基业股份有限公司&#xff08;SH: 600340&#xff0c;下称“华夏幸福”&#xff09;发布了关于债务逾期、债务重组进展等事项的公告。内容显示&#xff0c;华夏幸福截至1月…

MybatisPlus--03--IService、ServiceImpl

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 1. IService接口1.1 IService、ServiceImpl 接口的使用第一步&#xff1a;实现basemapper接口第二步&#xff1a;编写service类第三步&#xff1a;编写serviceImpl第…

白令海峡的题解

原题描述&#xff1a; 时间限制: 1000ms 空间限制: 524288kB 题目描述 很久很久以前&#xff0c;一座大陆桥横跨西伯利亚东端与美洲大陆西端。 处于进化早期的人类&#xff0c;正以部落的形式在大陆上游荡、捕猎&#xff0c;四海为家。在饥饿与寒冷折磨下&#xff0c;人…

开源软件:塑造软件行业未来的协作与创新之力

随着信息技术的迅猛发展&#xff0c;开源软件已经逐渐成为软件开发的潮流&#xff0c;以其独特的低成本、可协作性和透明度等特性&#xff0c;在全球范围内引起了广泛的关注和应用。越来越多的企业和个人选择使用开源软件&#xff0c;这不仅推动了软件行业的繁荣&#xff0c;还…

电路设计(27)——交通信号灯的multisim仿真

1.功能要求 使用数字芯片设计一款交通信号灯&#xff0c;使得&#xff1a; 主干道的绿灯时间为60S&#xff0c;红灯时间为45S 次干道的红灯时间为60S&#xff0c;绿灯时间为45S 主、次干道&#xff0c;绿灯的最后5S内&#xff0c;黄灯闪烁 使用数码管显示各自的倒计时时间。 按…

: ) 万字项目实践指南——贪吃蛇 手把手教你写出自己的小游戏!

目录 前言 1. 游戏背景 2. 游戏效果演示 3. 目标 4. 项目定位 5. 技术要点 6. Win 32 API 介绍 6.1 Win32 API 6.2 控制台程序&#xff08;Console) 6.3 控制台屏幕上的坐标COORD​ 6.4 GetStdHandle 6.5 GetConsoleCursorInfo 6.5.1 CONSOLE_CURSOR_INFO ​ 6.6 SetConsoleCur…

Yooasset、UniTask 使用遇到的一个奇怪的问题

先上截图 从截图可以看出 释放资源的方法是一个同步方法&#xff0c;但是执行释放资源的时候&#xff0c;竟然触发了我另一个地方的代码。 经检查&#xff0c;这个地方之所以会被执行&#xff0c;是因为Yooasset在释放资源的时候&#xff0c;激活了加载资源的等待。

迅为RK3568开发板驱动开发指南-输入子系统

《iTOP-RK3568开发板驱动开发指南》更新&#xff0c;本次更新内容对应的是驱动&#xff08;第十三篇 输入子系统&#xff09;视频&#xff0c;帮助用户快速入门&#xff0c;大大提升研发速度。 第13篇-输入子系统目录 第1篇 驱动基础篇 第2篇 字符设备基础 第3篇 并发与竞争 …

如何用jmeter请求application/octet-stream,image/jpeg

用postman调用时&#xff1a; 用jmeter&#xff1a; 注意上图不要勾选&#xff0c;不然会把所有的内容都以二进制传进去&#xff0c;我们不勾选只传二进制的图片内容&#xff0c;勾选了会把MIME类型、参数名称都转为二进制传进去。会报错。

网络知识

目录 IP地址(Internet protocol address) —— 互联网协议地址 子网掩码 网关 路由 DNS&#xff08;Domain Name Server&#xff09; —— 域名服务器 IP地址(Internet protocol address) —— 互联网协议地址 子网掩码 作用&#xff1a;划分网段 网络部分相同的IP地址&a…

【数据结构】排序(2)

目录 一、快速排序&#xff1a; 1、hoare(霍尔)版本&#xff1a; 2、挖坑法&#xff1a; 3、前后指针法&#xff1a; 4、非递归实现快速排序&#xff1a; 二、归并排序&#xff1a; 1、递归实现归并排序&#xff1a; 2、非递归实现归并排序&#xff1a; 三、排序算法…

实在智能签约国内头部燃气集团:用Agent加速数智化深入,量利双升建设智慧燃气

燃气是我国四大能源产业之一&#xff0c;是推进国民经济建设与生态保护协同发展的主战场&#xff0c;高速的发展机遇下伴随着诸多挑战&#xff1a;随着业务规模扩大&#xff0c;运营工作量和复杂度不断上升&#xff0c;考验企业的业态模式能力&#xff1b;运营各环节需投入大量…

基于springboot+vue的智能推荐的卫生健康系统(前后端分离)

博主主页&#xff1a;猫头鹰源码 博主简介&#xff1a;Java领域优质创作者、CSDN博客专家、阿里云专家博主、公司架构师、全网粉丝5万、专注Java技术领域和毕业设计项目实战&#xff0c;欢迎高校老师\讲师\同行交流合作 ​主要内容&#xff1a;毕业设计(Javaweb项目|小程序|Pyt…

你还不会大厂必考的10个经典排序算法吗?

公众号&#xff1a;程序员白特&#xff0c;欢迎一起交流学习~ 前言 众所周知&#xff0c;10个经典排序算法在大厂的校招、社招面试中频繁出现&#xff0c;那么今天我们就来用JS语言实现一下这10个经典排序算法吧。 概念 排序算法&#xff1a; 排序算法是《数据结构与算法》中…

vscode远程调试服务器的Python代码

目录 1 配置vscode远程阅读代码 2 打开conda环境 3 配置相应的调试环境 4 开始调试 这篇博客首先参考了我自己之前的两篇博客 vscode怎么查看python库的源代码/vscode打开conda环境 ubuntu上安装vscode&#xff0c;并远程开发与远程调试服务器代码 1 配置vscode远程阅读…