一、实习内容
模拟磁盘空闲空间的表示方法,以及模拟实现磁盘空间的分配和回收。
二、实习目的
磁盘初始化时把磁盘存储空间分成许多块(扇区),这些空间可以被多个用户共享。用户作业在执行期间常常要在磁盘上建立文件或把已经建立在磁盘上的文件删去,这就涉及到磁盘存储空间的分配和回收。一个文件存放到磁盘上,可以组织成顺序文件(连续文件)、链接文件(串联文件)、索引文件等,因此,磁盘存储空间的分配有两种方式,一种是分配连续的存储空间,另一种是可以分配不连续的存储空间。怎样有效地管理磁盘存储空间是操作系统应解决的一个重要问题,通过本实习使学生掌握磁盘存储空间的分配和回收算法。
三、实习题目
模拟UNIX系统的空闲块成组链接法,实现磁盘存储空间的管理
[提示]:
(1) 假定磁盘存储空间已被划分成长度为n的等长块,共有M块可供使用。UNIX系统中采用空闲块成组链接的方法来管理磁盘存储空间,将磁盘中的每N个空闲块(N<M)分成一组,最后一组可以不足N块,每组的第一块中登记了下一组空闲块的块数和块号,第一组的块数和块号登记在专用块中,登记的格式如下:
0 空闲块数k
1 空闲块号1
2 空闲块号2
… …
K 空闲块号k
当第一项内容为“0”时,则第二项起指出的空闲块是最后一组。
(2)可用二维数组A [0…M-1] [0…n-1]来模拟管理磁盘空间,用A[i]表示第I块,第0块A[0]作为专用块。
(3) 成组链接的分组情况记录在磁盘物理块中,为了查找链接情况,必须把它们读入主存,故当磁盘初始化后,系统先将专用块内容复制到主存中。定义一个数组MA存放专用块内容,即MA: =A[0]。申请一块磁盘空间时,查MA,从中找出空闲块号,当一组的空闲块只剩第一块时,则应把该块中指出的下一组的空闲块数和块号复制到专用块中,然后把该块分配给申请者。当一组的空闲块分配完后则把专用块内容(下一组链接情况)复制到主存,再为申请者分配。
(4) 归还一块时给出归还的块号,若当前组不满规定块数时,将归还块登记入该组;若当前组已满,则另建一新组,这时归还块作为新一组的第一块,应把主存中登记的一组链接情况MA复制到归还块中,然后在MA重新登记一个新组。
(5) 设计分配和归还磁盘空间的程序。
要求能接受来自键盘的空间申请及释放请求,能显示或打印分配的磁盘空间的块号,在完成一次分配或归还后能显示或打印各空闲块组的情况(各组的空闲块数和块号)。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace CaoZuoXiTong3
{
class Program
{
static public int[,] cache = new int[101, 101];//一行为一个块
static public int a;//用来展示分组情况的两个变量
static public int b;
static void Main(string[] args)
{
Console.WriteLine("假设共有100块可用,每5块为一组");
for(int i = 0; i < 100; i++)
{
cache[i, 100] = 1;//置为1表示可用
}
//初始化专用块
{
cache[0, 0] = 5;
cache[0, 1] = 1;
cache[0, 2] = 2;
cache[0, 3] = 3;
cache[0, 4] = 4;
cache[0, 5] = 5;
}
//分组
for (int i = 1; i < 92; i = i + 5)
{
cache[i, 0] = 5;
cache[i, 1] = i + 5;
cache[i, 2] = i + 6;
cache[i, 3] = i + 7;
cache[i, 4] = i + 8;
cache[i, 5] = i + 9;
}
{
cache[96, 0] = 0;
cache[96, 1] = 0;
cache[96, 2] = 0;
cache[96, 3] = 0;
cache[96, 4] = 0;
cache[96, 5] = 0;
}
int judge = 0;
while (judge != 4)
{
Console.WriteLine("\n输入1申请块,输入2释放块,输入3显示分组情况,输入4退出:");
judge = Convert.ToInt32(Console.ReadLine());
switch (judge)
{
case 1: Request(); break;
case 2: Release(); break;
case 3: a = 0; b = 0; Show(); break;
case 4: judge = 4; break;
}
}
}
static void Request()
{
Console.WriteLine("请输入需要申请的块数:");
int number = Convert.ToInt32(Console.ReadLine());
Console.WriteLine("分配的块号为:\n" );
while (number != 0)
{
if (cache[0,0] > 1)
{
int i = 0;
for (int a = 99; a>0; a--)
{
if (cache[0, a] != 0)
{
i = cache[0, a];
cache[0, a] = 0;
break;
}
}
cache[i, 100] = 0;//把这个块分配出去
cache[0, 0]--;
Console.Write(" " + i);
}
else
{
if (cache[0,0] == 0)
{
Console.WriteLine("磁盘空间已用尽");
break;
}
int a = cache[0,1];//记录下一块的块号
for (int i = 0; i < 101; i++)//拷入专用块
{
cache[0,i] = cache[a, i];
}
cache[a, 100] = 0;//分配出去
Console.Write(" " + a);
}
number--;
}
Console.WriteLine("\n");
}
static void Release()
{
Console.WriteLine("请输入要回收的磁盘号:");
int a = Convert.ToInt32(Console.ReadLine());
if (cache[a, 100] == 0)
{
for (int i = 0; i < 100; i++)
{
cache[a, i] = 0;
}
if (cache[0, 0] != 5)
{
if (cache[0, 0] == 0)//96块进入专用块的情况
{
cache[0, 1] = a;
cache[0, 0]++;
}
else
{
for (int i = 0; i < 6; i++)
{
if (cache[0, i] != 0 && cache[0, i + 1] == 0)
{
cache[0, i + 1] = a;
cache[0, 0]++;
break;
}
}
}
}
else
{
for (int i = 0; i < 100; i++)
{
cache[a, i] = cache[0, i];
}
cache[0, 0] = 1;
cache[0, 1] = a;
for (int i = 2; i < 100; i++)
{
cache[0, i] = 0;
}
}
cache[a, 100] = 1;
Console.WriteLine("已回收");
}
else
{
Console.WriteLine("重复回收");
}
}
static void Show()
{
if (cache[a,0]!=0)
{
Console.Write("\n"+"第{0}组:可用块数{1}"+" ", b, cache[a, 0]);
Console.Write(" 可用块号:");
for(int i = 1; i < 100; i++)
{
if (cache[a, i] != 0) Console.Write(cache[a,i]+" ");
}
a = cache[a, 1];
b++;
Show();
}
}
}
}
才疏学浅,如有错误请多指正