操作系统实验——连续存储管理仿真

一、固定分区存储管理

1.固定分区分配

1.1 原理

将用户空间划分为若干个固定大小的分区,在每个分区中只装入一道作业

1.2 方式

分区大小相等:缺乏灵活性,但是很适合于用一台计算机控制多个相同对象的场合

分区大小不等:增加了灵活性,可以满足不同大小的基础南横需求。根据常在系统中运行的作业大小情况进行划分

1.3 分区使用表

操作系统需要建立一个数据结构—分区说明表。来实现各个分区的分配与回收。每个表对应一个分区,通常按照分区大小排列

每个表包括对应分区的大小、起始地址、状态等,详见2.1

1.4 优点

实现简单,无外部碎片

1.5 缺点

当用户程序太大时,可能所有的分区都不能满足需求,此时不得不采用覆盖技术来解决,但这又会降低性能

会产生内部碎片,内存利用率低

2. 仿真实现

2.1 分区使用表

// Partition description
struct PD
{
    int id;        // 分区号
    int begin;     // 起始位置
    int size;      // 分区大小
    bool flag;     // 是否分配
    int isUseSize; // 已使用大小
    PD() {}
    PD(int id, int begin, int size)
    {
        this->id = id;
        this->begin = begin;
        this->size = size;
        flag = false;
        isUseSize = 0;
    }
};
vector<PD> PDTable;

2.2 分区初始化

// 大 中 小 分区的个数
const int bigPartitionNum = 5;
const int middlePartitionNUm = 20;
const int smallPartitionNum = 10;

// 大 中 小 分区的大小

const int bigPartitionSize = 256;
const int middlePartitionSize = 64;
const int smallPartitionSize = 16;

// 内存起始位置
const int BEGIN = 0;

// 初始化分区使用表
void init()
{
    // 分区号
    int id = 1;

    for (int i = 0; i < smallPartitionNum; i++)
    {
        PD p(id, BEGIN + i * smallPartitionSize, smallPartitionSize);
        PDTable.push_back(p);
        id++;
    }
    int middleBegin = BEGIN + smallPartitionNum * smallPartitionSize;
    for (int i = 0; i < middlePartitionNUm; i++)
    {
        PD p(id, middleBegin + i * middlePartitionSize, middlePartitionSize);
        PDTable.push_back(p);
        id++;
    }
    int bigBegin = middleBegin + middlePartitionNUm * middlePartitionSize;
    for (int i = 0; i < bigPartitionNum; i++)
    {
        PD p(id, bigBegin + i * bigPartitionSize, bigPartitionSize);
        PDTable.push_back(p);
        id++;
    }
}

2.3 分配作业

/**
 * 分配作业
 * 分配成功返回true  分配失败返回false
 * 参数:作业ID  作业大小
 */
bool allocate(int id, int size)
{
    // 从分区号最低的分区开始遍历  直到找到第一个符合要求的分区
    for (int i = 0; i < PDTable.size(); i++)
    {
        // 如果已经分配则跳过
        if (PDTable[i].flag)
            continue;

        if (PDTable[i].size >= size)
        {
            PDTable[i].flag = true;
            PDTable[i].isUseSize = size;
            PDTable[i].workId = id;

            return true;
        }
    }
    return false;
}

2.4 统计内部碎片

/**
 * 统计内部碎片(memory fragmentation)大小
 */

int getMemoryFragmentationSize()
{
    int res = 0;
    for (int i = 0; i < PDTable.size(); i++)
    {
        if (PDTable[i].flag)
        {
            res += PDTable[i].size - PDTable[i].isUseSize;
        }
    }
    return res;
}

2.5 查看作业分配情况

/**
 * 查看作业分配情况
 */
void show()
{
    cout << setw(10) << "分区号" << setw(10) << "分区大小" << setw(15) << "分区起始地址" << setw(10) << "分区状态" << setw(15) << "分配作业号" << setw(15) << "内部碎片大小" << endl;
    for (int i = 0; i < PDTable.size(); i++)
    {
        cout << setw(10) << PDTable[i].id;
        cout << setw(10) << PDTable[i].size;
        cout << setw(15) << PDTable[i].begin;
        cout << setw(10) << (PDTable[i].flag == true ? "已分配" : "未分配");
        if (PDTable[i].flag)
        {
            cout << setw(15) << PDTable[i].workId;
            cout << setw(15) << PDTable[i].size - PDTable[i].isUseSize;
        }
        cout << endl;
    }
}

2.6 创建测试样例 测试

// 待分配作业
const pair<int, int>
    work[] = {{1, 12}, {2, 16}, {3, 20}, {4, 25}, {5, 52}, {6, 64}, {7, 78}, {8, 92}, {9, 156}, {10, 230}, {11, 290}};

int main()
{
    // 初始化
    init();

    // 记录分配成功的情况
    int success = 0;

    // 分配作业
    for (int i = 0; i < 11; i++)
    {
        success += allocate(work[i].first, work[i].second);
    }

    // 分配作业情况
    show();
    cout << "分配成功的作业数:" << success << "     分配失败的作业数:" << 11 - success << endl;

    cout << "内部碎片大小:" << getMemoryFragmentationSize() << endl;
}

2.7 结果截图

image-20240610220404919

posted @ 2024-06-10 22:10  Gu_diao  阅读(43)  评论(0)    收藏  举报