操作系统实验实验二分区式存储管理

实验内容

设计程序模拟内存的动态分区法存储管理。内存空闲区使用自由链管理,采用最坏适应算法从自由链中寻找空闲区进行分配,内存回收时假定不做与相邻空闲区的合并。假定系统的内存共 640K ,初始状态为操作系统本身占用 64K 。在 tl 时间之后,有作业 A 、 B 、 c 、D 分别请求 8K 、 16K 、 64K 、 124K 的内存空间;在 t2 时间之后,作业 c 完成;在 t3 时间之后,作业E 请求 50K 的内存空间;在 t4 时间之后,作业 D 完成。要求编程序分别输出 tl 、 t2 、 t3 、 t4 时刻内存的空闲区的状态。

注意

如果遇到在visual stdio编译报错,报错内容是std::至少需要c++17。请查询如何修改编译器C++编译版本

时隔多日有同学向我反馈using iterator_deque = std::_Deque_iterator<std::pair<int, int>, std::pair<int, int> &, std::pair<int, int> *>;在visualStudio报错问题,由于我使用的是CLion。查了一下在visualStudio应该写成using iterator_deque = std::deque<std::pair<int, int>>::iterator;

实现步骤

设置一个busyLink

struct busyLink {
    char name;
    int len;
    int address;

// 三个适用于不同情形的构造函数
    busyLink() : name('\0'), len(0), address(0) {}

    busyLink(char _name) : name(_name), len(0), address(0) {}

    busyLink(char _name, int _len, int _address)
            : name(_name), len(_len), address(_address) {}
};

using busyNode = struct busyLink;

实现一个WF类,包含必要的两个类成员,以及一个记录剩余内存空间的变量

其中free_que空闲分区链中每一个结点,是一个包含长度和起始地址的对(pair)

private:
//包含#include <deque>头文件
	using ilen = int;
	using iaddres = int;
    std::deque<std::pair<ilen, iaddres>> *free_que;  // 空闲分区链表
    std::deque<busyNode> *busy_que; 	// 内存占用区链表 结点内容为busyNode

	int All_Memory = 640;     // 给定系统的内存共640K

利用构造函数初始化两个队列

// 初始化两个队列
public:
    // 利用构造函数 初始化成员
    WF() {
        busy_que = new std::deque<busyNode>();
        free_que = new std::deque<std::pair<ilen, iaddres>>();
        // 内存占用区 初始为OS本身所占用的64K内存 起始地址为0
        busy_que->emplace_front(busyNode{'S', 64, 0});
        // 初始空闲区
        free_que->emplace_front(std::pair<int, int>{All_Memory - 64, 64});
        All_Memory -= 64;
    }

实现类成员函数,模拟分配内存
在分配之前,对空闲分区进行从大到小的排序,使第一块分区永远是最大的一块分区

// 模拟分配内存 参数作业名 请求长度
    inline void requireMemo(char name, int require_len) {
        // 对空闲分区排序
        std::sort(free_que->begin(), free_que->end(),
                  [=](std::pair<int, int> a, std::pair<ilen, iaddres> b) {
                      return a.first > b.first;
                  });
         //
        if (free_que->front().first >= require_len) {         // 有足够的空闲分区
            busyNode new_node = busyNode(name);
            new_node.address = busy_que->back().len + busy_que->back().address;
            new_node.len = require_len;
            busy_que->push_back(new_node);
            All_Memory -= require_len;
            //更新free_que
            free_que->front().first = All_Memory;
            free_que->front().second = busy_que->back().len + busy_que->back().address;
        } else {
            std::cout << "Can't allocation!";
            exit(EXIT_FAILURE);
        }
    }

实现类成员函数,模拟内存回收

 // 模拟内存回收
 public:
    inline void freeMemo(char name) {
        for (auto it = busy_que->begin(); it != busy_que->end(); ++it) {
            if (it->name == name) {		// 找到要被回收的作业名
            	// 在空闲分区中新增被回收的内存空间
                free_que->emplace_back(std::pair<int, int>{it->len, it->address});
                // 删除
                busy_que->erase(it);
                break;
            }
        }
    }

实现类成员函数,对相邻的空闲分区进行合并
:作业A和作业B相邻,就是说作业A的起始地址+作业A的长度等于作业B的起始地址

public:
    // 将空闲分区相邻的内存进行合并
    inline void MergerFreeMemo() {
        // 对空闲分区排序
        std::sort(free_que->begin(), free_que->end());
        if (free_que->size() <= 1) return;
        for (int i = 1; i < free_que->size(); ++i) {
            if ((free_que->begin() + i)->second ==
                (free_que->begin() + i - 1)->second + (free_que->begin() + i - 1)->first) {
                //如果当前内存的起始地址 是上一个的起始地址+长度之和 说明它们相邻
                Merge(free_que->begin() + i - 1, free_que->begin() + i);
            }
        }
    }
protected:
using iterator_deque = std::_Deque_iterator<std::pair<int, int>, 
							std::pair<int, int> &, std::pair<int, int> *>;
    // 对两个内存两块进行合并 参数是迭代器
    inline void Merge(iterator_deque m1, iterator_deque m2) {
        m1->first += m2->first;
        free_que->erase(m2);
    }

完整代码

#include <iostream>
#include <queue>
#include <vector>
#include <string>
#include <algorithm>

// 声明别名
using ilen = int;
using iaddres = int;
using iterator_deque = std::_Deque_iterator<std::pair<int, int>, 
							std::pair<int, int> &, std::pair<int, int> *>;

// 模拟时间点
enum Time {
    t1, t2, t3
};

struct busyLink {
    char name;
    int len;
    int address;

    busyLink() : name('\0'), len(0), address(0) {}

    busyLink(char _name) : name(_name), len(0), address(0) {}

    busyLink(char _name, int _len, int _address)
            : name(_name), len(_len), address(_address) {}
};

using busyNode = struct busyLink;

// Worst Fit 最坏适应动态分区匹配算法
class WF {
public:
    // 利用构造函数 初始化成员
    WF() {
        busy_que = new std::deque<busyNode>();
        free_que = new std::deque<std::pair<ilen, iaddres>>();
        // 内存占用区 初始为OS本身所占用的64K内存 起始地址为0
        busy_que->emplace_front(busyNode{'S', 64, 0});
        // 初始空闲区
        free_que->emplace_front(std::pair<int, int>{All_Memory - 64, 64});
        All_Memory -= 64;
    }

    inline void past(int time) {
        printf("时间%d", time);
    }

    // 模拟分配内存 参数作业名 请求长度
    inline void requireMemo(char name, int require_len) {
        // 对空闲分区排序
        std::sort(free_que->begin(), free_que->end(),
                  [=](std::pair<int, int> a, std::pair<ilen, iaddres> b) {
                      return a.first > b.first;
                  });
        if (free_que->front().first >= require_len) {         // 有足够的空闲分区
            busyNode new_node = busyNode(name);
            new_node.address = busy_que->back().len + busy_que->back().address;
            new_node.len = require_len;
            busy_que->push_back(new_node);
            All_Memory -= require_len;
            //更新free_que
            free_que->front().first = All_Memory;
            free_que->front().second = busy_que->back().len + busy_que->back().address;
        } else {
            std::cout << "Can't allocation!";
            exit(EXIT_FAILURE);
        }
    }

    // 模拟内存回收
    inline void freeMemo(char name) {
        for (auto it = busy_que->begin(); it != busy_que->end(); ++it) {
            if (it->name == name) {
                free_que->emplace_back(std::pair<int, int>{it->len, it->address});
                busy_que->erase(it);
                break;
            }
        }
    }

    inline void print() const {
        printf("内存占用区为:\n");
        printf("作业名\t起始地址\t长度\n");
        for (auto it = busy_que->begin(); it != busy_que->end(); ++it) {
            printf("%c\t\t%d\t\t%d\n", it->name, it->address, it->len);
        }
        printf("内存空间区为:\n");
        printf("起始地址\t大小\n");
        for (auto it = free_que->begin(); it != free_que->end(); ++it) {
            printf("%d\t\t%d\n", it->second, it->first);
        }
        printf("--------------------------------------\n");
    }

    // 将空闲分区相邻的内存进行合并
    inline void MergerFreeMemo() {
        // 对空闲分区排序
        std::sort(free_que->begin(), free_que->end());
        if (free_que->size() <= 1) return;
        for (int i = 1; i < free_que->size(); ++i) {
            if ((free_que->begin() + i)->second ==
                (free_que->begin() + i - 1)->second + (free_que->begin() + i - 1)->first) {
                //如果当前内存的起始地址 是上一个的起始地址+长度之和 说明它们相邻
                Merge(free_que->begin() + i - 1, free_que->begin() + i);
            }
        }
    }

    ~WF() = default;

protected:
    // 对两个内存两块进行合并 参数是迭代器
    inline void Merge(iterator_deque m1, iterator_deque m2) {
        m1->first += m2->first;
        free_que->erase(m2);
    }

private:
    std::deque<std::pair<ilen, iaddres>> *free_que;      // 空闲分区链表 其中每一个结点{包含分区长度(first),分区起始地址(second)}
    std::deque<busyNode> *busy_que;                 // 内存占用区链表 结点内容为busyNode定义在第7行
    int All_Memory = 640;     // 给定系统的内存共640K
};

int main() {
    WF wf;
    wf.past(t1);
    wf.requireMemo('A', 8);
    wf.requireMemo('B', 16);
    wf.requireMemo('C', 64);
    wf.requireMemo('D', 124);
    wf.print();
    wf.past(t2);
    wf.freeMemo('C');
    wf.print();
    wf.past(t3);
    wf.requireMemo('E', 50);
    wf.print();
    wf.freeMemo('D');
    wf.print();
    std::cout << "\n对空闲分区进行合并\n";
    wf.MergerFreeMemo();
    wf.print();
    return 0;
}

至此,实验二已经完成。

由于本人技术有限,代码中不免存在纰漏,还望见谅。💕💕💕

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

打代码要笑着打

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值