操作系统第三次实验-动态分区存储管理(python代码实现)

news2024/9/29 5:36:12

一、实验目的:

目的:熟悉并掌握动态分区分配的各种算法,熟悉并掌握动态分区中分区回收的各种情况,并能够实现分区合并。
任务:用高级语言模拟实现动态分区存储管理。

二、实验内容:

1、实验内容
分区分配算法至少实现首次适应算法、最佳适应算法和最坏适应算法中的至少一种。熟悉并掌握各种算法的空闲区组织方式。
分区的初始化——可以由用户输入初始分区的大小。(初始化后只有一个空闲分区,起始地址为0,大小是用户输入的大小)
分区的动态分配过程:由用户输入作业号和作业的大小,实现分区过程。
分区的回收:用户输入作业号,实现分区回收,同时,分区的合并要体现出来。(注意:不存在的作业号要给出错误提示!)
分区的显示:任何时刻,可以查看当前内存的情况(起始地址是什么,大小多大的分区时空闲的,或者占用的,能够显示出来)。
2、实验要求
(1)内存空间不足的情况,要有相应的显示;
(2)作业不能同名,但是删除后可以再用这个名字;
(3)作业空间回收是输入作业名,回收相应的空间,如果这个作业名不存在,也要有相应的提示;
(4)实现FF、BF、WF内存分配算法种的至少两种。
(5)实验完成后要参加实验答辩。

三、实验代码

import copy
class Memory(object):
    def __init__(self, start, end, length, state=1, name=0): 
        self.start = start
        self.end = end
        self.length = length
        self.state = state  # state为1表示内存未分配
        self.name = name  ##name为0是未分配,其余为作业名称


class CustomError(Exception):
    def __init__(self, ErrorInfo):
        super().__init__(self)
        self.errorinfo = ErrorInfo

    def __str__(self):
        return self.errorinfo


def showMemory(list):
    print("分配状态\t分区名称\t起始地址\t终止地址\t分区大小")
    for i in range(0, len(list)):
        p = list[i]
        if p.state == 1:
            print('空闲\t', "    ", p.name, "      ", p.start, "  ", p.end, "    ", p.length)
        else:
            print('已分配\t', "", p.name, "      ", p.start, "  ", p.end, "    ", p.length)
    print("")


# 首次适应算法
def FF(work_name, work_length, list):
    for i in list:
        if i.name == work_name:
            print('作业已存在')
            return
    for i in range(0, len(list)):
        p = list[i]
        if p.state == 1 and p.length > work_length:  # p是当前未分配内存的大小
            a = Memory(p.start, p.start + work_length - 1, work_length, state=0, name=work_name)  # a是当前为作业分配的分区
            node2 = Memory(p.start + work_length, p.end, p.length - work_length, 1, 0)  # 空闲分区
            del list[i]  # 删除当前的分区
            list.insert(i, node2)  # 插入空闲分区
            list.insert(i, a)  # 插入已分配当前作业的分区
            showMemory(list)
            return
        if p.state == 1 and p.length == work_length:
            del list[i]  # 删除当前的分区
            a = Memory(p.start, p.start + work_length - 1, work_length, state=0, name=work_name)
            list.insert(i, a)
            showMemory(list)
            return
    print("内存空间不足")


def freeMemory(work_name, li):
    names = []
    for i in range(0, len(li)):
        names.append(li[i].name)
    if work_name not in names:
        print("作业%s不存在..." % work_name)
        return
    for i in range(0, len(li)):
        p = li[i]
        if p.name == work_name:
            p.state = 1  # 状态设为未分配
            target = i  # 记录该分区的位置
            p.name = 0  # 名称设置为初始0
            break

    # 向前合并空闲块
    if target - 1 >= 0:
        if li[target - 1].state == 1:  # 如果前一个分区是未分配状态

            a = Memory(li[target - 1].start, li[target].end, li[target - 1].length + li[target].length, 1, 0)
            del li[target - 1]  # 删除前一个分区
            del li[target - 1]  # 删除当前的分区
            li.insert(target - 1, a)
            target = target - 1  # 此步非常关键,将target指针指向已合并的分区,如果该分区后还有空闲分区,则可直接处理

    # 向后合并空闲块
    if target + 1 < len(li):
        if li[target + 1].state == 1:  # 如果后一个分区是未分配状态
            a = Memory(li[target].start, li[target + 1].end, li[target].length + li[target + 1].length, 1, 0)
            del li[target]
            del li[target]
            li.insert(target, a)
    showMemory(li)


##最佳适应算法
def select_sort(list):
    # 按分区的大小从小到大排序
    count = len(list)
    for i in range(0, count):
        for j in range(i + 1, count):
            if list[i].length <= list[j].length:
                list[i], list[j] = list[j], list[i]
    return list

def select_sort2(list):
    # 按分区的大小从大到小排序
    count = len(list)
    for i in range(0, count):
        for j in range(i + 1, count):
            if list[i].length >= list[j].length:
                list[i], list[j] = list[j], list[i]
    return list


def BF(work_name, work_length, li):
    for i in li:
        if i.name == work_name:
            print('作业已存在')
            return
    q = copy.copy(li)
    q = select_sort(q)  # 从小到大排序,给所有已分配和未分配的分区排序
    s = -1
    s2 = -1
    for i in range(0, len(q)):
        p = q[i]
        if p.state == 1 and p.length > work_length:  # 分区若为未分配
            s = p.start  # s得到起始位置
        elif p.state == 1 and p.length == work_length:
            s2 = p.start
    if s == -1 and s2 == -1:
        print("内存空间不足")
        return
    for i in range(0, len(li)):
        p = li[i]
        if p.start == s:
            a = Memory(p.start, p.start + work_length - 1, work_length, state=0, name=work_name)  # 修改后的分区
            node2 = Memory(p.start + work_length, p.end, p.length - work_length, 1, 0)  # 空闲分区
            del li[i]
            li.insert(i, node2)
            li.insert(i, a)
            showMemory(li)
            return
        elif p.start == s2:
            p.state = 0
            p.name = work_name
            showMemory(li)
            return


def WF(work_name, work_length, li):
    for i in li:
        if i.name == work_name:
            print('作业已存在')
            return
    q = copy.copy(li)
    q = select_sort2(q)  # 从大到小排序,给所有已分配和未分配的分区排序
    s = -1
    s2 = -1
    for i in range(0, len(q)):
        p = q[i]
        if p.state == 1 and p.length > work_length:  # 分区若为未分配
            s = p.start  # s得到起始位置
        elif p.state == 1 and p.length == work_length:
            s2 = p.start
    if s == -1 and s2 == -1:
        print("内存空间不足")
        return
    for i in range(0, len(li)):
        p = li[i]
        if p.start == s:
            a = Memory(p.start, p.start + work_length - 1, work_length, state=0, name=work_name)  # 修改后的分区
            node2 = Memory(p.start + work_length, p.end, p.length - work_length, 1, 0)  # 空闲分区
            del li[i]
            li.insert(i, node2)
            li.insert(i, a)
            showMemory(li)
            return
        elif p.start == s2:
            p.state = 0
            p.name = work_name
            showMemory(li)
            return


if __name__ == '__main__':

    while True:
        try:
            print("请输入合法内存大小:")
            size = int(input())
            a = Memory(0, size - 1, size, state=1, name=0)
            memorySpace = []
            memorySpace.append(a)
            print("1.首次适应算法(FF)")
            print("2.最佳适应算法(BF)")
            print("3.最佳适应算法(WF)")
            choice = int(input("请输入分配执行的算法:\n"))
            if choice not in [1, 2, 3]:
                raise CustomError("输入错误,请重新输入")
        except Exception as e:
            print(e)
        else:
            print("大小为%d的内存空间已完成初始化..." % size)
            # showMemory(memorySpace)
            print("")
            break
    # while True:
    #     print('1:初始化\t\n2:分配空间\t\n3:回收\t\n4:显示\t\n5:退出\n')
    while (True):
        print('1:初始化\t\n2:分配\t\n3:回收\t\n4:显示\t\n5:退出')
        select = input('请输入想要执行的功能:')
        if select == '5':
            break
        elif select == '1':
            print("请输入合法内存大小:")
            size = int(input())
            a = Memory(0, size - 1, size, state=1, name=0)
            memorySpace = []
            memorySpace.append(a)
        elif select == '2':
            repeat = 'y'
            while (repeat == 'y'):
                if choice == 1:  # FF算法
                    try:
                        workSize = input('请输入作业名称和大小:').split()
                        FF(workSize[0], int(workSize[1]), memorySpace)
                    except Exception as e:
                        print("输入有误,请重新输入")
                    else:
                        repeat = input('是否继续(y/n):')
                elif choice == 2:  # BF算法
                    try:
                        workSize = input('请输入作业名称和大小:').split()
                        BF(workSize[0], int(workSize[1]), memorySpace)
                    except Exception as e:
                        print("输入有误,请重新输入")
                    else:
                        repeat = input('是否继续(y/n):')
                elif choice == 3:  # WF算法
                    try:
                        workSize = input('请输入作业名称和大小:').split()
                        WF(workSize[0], int(workSize[1]), memorySpace)
                    except Exception as e:
                        print("输入有误,请重新输入")
                    else:
                        repeat = input('是否继续(y/n):')

        elif select == '3':
            showMemory(memorySpace)
            workName = input('请输入所要删除作业的名称:')
            freeMemory(workName, memorySpace)
        else:
            showMemory(memorySpace)

四、实验结果

1.首先输入合法内存大小:50,并选择最坏适应算法WF:
在这里插入图片描述
2.选择2,依次进行三个作业的内存分配:
在这里插入图片描述
3.1)对于数据1,60,作业大小超过分区的总大小,因此提示“内存空间不足”;
3.2)对于数据1,10,存在大于等于该作业大小的分区0,因此分配至分区0;
3.3)对于数据1,20,因为分区中已经存在同名作业,因此提示“作业已存在”;
3.4)对于数据2,20,存在大于等于该作业大小的分区0,因此分配至分区0;

4.选择3进行内存的回收,回收作业1:
在这里插入图片描述
作业1所在分区状态变为“空闲”,名称变为默认值。

6.回收作业2:
在这里插入图片描述
回收区2前后有空闲区,一块进行合并回收形成一个空闲分区。
7.分配大小为10的作业1:
在这里插入图片描述
8.分配大小为10的作业2:
在这里插入图片描述
9.分配大小为9的作业3:
在这里插入图片描述
10.回收作业1:
在这里插入图片描述
11.分配大小为11的作业4:
在这里插入图片描述
只有大小为21的分区满足作业4,因此分配至最后一个分区。
12.分配大小为5的作业1:
在这里插入图片描述
第一个分区和最后一个分区的大小都为10,内存大小的情况下,地址靠前的分区优先分配,因此将作业1分配至第一个分区。
13.回收作业2:
在这里插入图片描述
回收区2前面有一个空闲分区,将其合并为一个空闲分区。
14.回收作业4:

在这里插入图片描述
回收区3后面有一个空闲分区,将其合并为一个空闲分区。
15.回收作业1:
在这里插入图片描述
回收区1后面有一个空闲分区,将其合并为一个空闲分区。
16.回收作业3:
在这里插入图片描述
回收区3前后各有一个空闲分区,将其合并为一个空闲分区。

FF首次适应算法和BF最佳适应算法测试方法与之类似,结果符合预期。

五、实验总结

通过本次动态分区存储管理实验,我熟悉并掌握了动态分区分配的三种算法:FF首次适应算法、BF最佳适应算法和WF最坏适应算法及其相应的分区组织方式。此外我掌握了不同情况下的分区回收,包括回收区前有空闲区,回收区后有空闲区,回收区前后有空闲区;

在具体的代码实现中,我采用的是Python语言,因为Python中列表这一数据结构可以较为简便地实现分区的增删改,在处理BF和WF内存分配算法时需要注意在分区空间相同时优先向低地址的分区分配作业,这个要求的实现如果不细想的话可能觉得比较复杂,实际在仔细考虑之后只需将排序算法中小于或大于的比较中加上等号就可实现了,因为本身分区是按地址从小到大依次排序的,那么在加上等号之后就可实现在新的排序中即使分区的大小相同,也是地址较小的靠前。

同时在合并空闲分区的这一过程中,有一个十分关键的操作:target = target - 1,在合并完回收区的前一个空闲分区后可以使target指针重新指向已合并后的分区,如果该分区后还有空闲分区则可直接利用对后面空闲分区处理的函数,使得代码更加地简洁。

其次对于实验要求中的三个要求,对于内存空间不足的情况需要给出内存不足的提示的实现,可以通过遍历内存空间中的空闲分区将其空间与作业的空间进行比较,若所有分区的大小都小于作业的大小,则给出“内存空间不足”的它提示;对于分配时作业不能同名的这一要求,实现较为简单,通过遍历分区名称并与作业的名称进行比较,如果相同则直接return返回;对于作业空间回收时若作业名不存在的提示,实现与上述做法类似。

总之这次实验大大地加深了我对动态分区存储管理的理解,其次也进一步锻炼了自身的coding能力,是一次收获不小的实验。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/139270.html

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

相关文章

Qt 编译出的程序无法在其他电脑运行

明确构建套件&#xff08;Kit&#xff09; Kit 包含了构建程序所需的全部工具&#xff0c;例如编译器&#xff0c;可以从Qt Creator 左下角查看Kit。 我这里使用的Kit是Desktop Qt 5.12.6 MinGW 64-bit 打开 Kit 版本对应的 Qt 命令行工具 我这里需要打开Qt 5.12.6 (MinGW 7.3…

php反序列化字符逃逸

php反序列化字符逃逸 php反序列化字符逃逸的原理 当开发者使用先将对象序列化&#xff0c;然后将对象中的字符进行过滤&#xff0c;最后再进行反序列化。这个时候就有可能会产生PHP反序列化字符逃逸的漏洞。 php反序列化字符逃逸分类 过滤后字符变多 过滤后字符变少 过滤后字…

Alma Linux和Rocky Linux,你会选择用哪个?

AlmaLinux和Rocky Linux是两个基于 Red Hat Enterprise Linux (RHEL) 发行版的免费开源操作系统&#xff0c;两者都旨在由社区驱动、透明且稳定&#xff0c;但两者之间存在一些关键差异。 Rocky Linux Rocky Linux 是一个基于 Red Hat Enterprise Linux (RHEL) 发行版的免费开…

Android 音视频学习之《MediaCodec》

一、介绍以及编解码流程 MediaCodec 类可用于访问低级媒体编解码器&#xff0c;即编码器/解码器组件。它是 Android 低级多媒体支持基础结构的一部分&#xff08;通常与MediaExtractor、MediaSync、MediaMuxer、MediaCrypto、 MediaDrm、Image、Surface和一起使用AudioTrack。…

060-MySQL数据库综合应用(实现登录及注册功能源代码)

【上一讲】059-MySQL数据库综合应用(实现登录及注册功能)_CSDN专家-赖老师(软件之家)的博客-CSDN博客 本文章讲解JAVA数据库技术与MySQL数据库结合使用,利用DAO技术对数据库操作进行封装,达到高内聚低耦合,具体技术如下: 1.综合利用JAVA数据库技术,掌握Connection,St…

操作系统第四次实验-基本分页存储管理(python代码实现)

一、实验目的&#xff1a; 目的&#xff1a;熟悉并掌握基本分页存储管理的思想及其实现方法&#xff0c;熟悉并掌握基本分页存储管理的分配和回收方式。 任务&#xff1a;模拟实现基本分页存储管理方式下内存空间的分配和回收。 二、实验内容&#xff1a; 1、实验内容 内存空间…

一道有意思的图论题

今天写这道题的过程就一直在摆&#xff0c;主要是写不太出来&#xff0c;之前想到动态规划去了&#xff0c;然后又开始深搜&#xff0c;在出口那块放动态规划 题&#xff1a; D. Ela and the Wiring Wizard 点我 但是cf让我明白了一个道理&#xff0c;任何一道我写不出来的题代…

点菜方案数

题目描述 不过uim的口袋里只剩 M元(M < 10000)&#xff0c;来到了一家低端餐馆前。 餐馆虽低端&#xff0c;但是菜品种类不少&#xff0c;有 N 种(N < 100)&#xff0c;第i种卖元(ai < 1000)。由于是很低端的餐馆所以每种菜只有一份。 uim奉行“不把钱吃光不罢休”&a…

作用域与作用域链

javascript拥有一套设计良好的规则来存储变量&#xff0c;并且之后可以方便的找到这些变量&#xff0c;这套规则叫做作用域。 内部原理 内部原理分成编译、执行、查询、嵌套和异常五部分。今天来简单说一下查询。 var a2;这行代码中&#xff0c;在引擎执行的第一步操作中&am…

【C++ Primer】阅读笔记(3):decltype

目录 简介decltype基础decltype需要注意的地方1.decltype处理顶层const、引用与auto不同2.如果decltype使用的表达式不是一个变量,则decltype返回表达式结果对应的类型。3.如果表达式的内容是解引用操作,则decltype会得到引用类型。4.对于decltype所用的表达式来说,如果变量…

Spring AOP统一功能处理

⭐️前言⭐️ 这篇文章主要介绍AOP&#xff08;Aspect Oriented Programming&#xff09;——面向切面编程的思想&#xff0c;它是对某一类事情的集中处理&#xff0c;也是对OOP&#xff08;Object Oriented Programming&#xff09;面向对象编程的补充和完善。 &#x1f349;…

【编程语言选择】我们学C++将来能做什么?

首先贴上C嘎嘎祖师爷的镇楼帅照&#x1f606; 凝视目录 什么是C C的使用广泛度 C的具体工作领域有什么 什么是C 简单说 C是基于C语言而产生的&#xff0c;它既可以进行C语言的过程化程序设计&#xff0c;又可以进行以抽象数据类型为特点的基于对象的程序设计&#xff0c;还可…

【区块链 | 前端】前端开发人员入门区块链的最佳实践

前端开发人员入门区块链的最佳实践 一. 建立信仰 从技术入门一个行业通常是漫无目的&#xff0c;个人认为正确的入行区块链的方式是去了解他的背景&#xff0c;是去建立自己信仰的&#xff0c;尤其身处一个刚起步就被扼杀的行业&#xff0c;我们每个人都是领头人&#xff0c;我…

06栈和队列

开始系统学习算法啦&#xff01;为后面力扣和蓝桥杯的刷题做准备&#xff01;这个专栏将记录自己学习算法是的笔记&#xff0c;包括概念&#xff0c;算法运行过程&#xff0c;以及代码实现&#xff0c;希望能给大家带来帮助&#xff0c;感兴趣的小伙伴欢迎评论区留言或者私信博…

[NOIP 2003] 栈(三种方法:DP、数论、搜索)

[NOIP2003 普及组] 栈 题目背景 栈是计算机中经典的数据结构&#xff0c;简单的说&#xff0c;栈就是限制在一端进行插入删除操作的线性表。 栈有两种最重要的操作&#xff0c;即 pop&#xff08;从栈顶弹出一个元素&#xff09;和 push&#xff08;将一个元素进栈&#xff…

5 个必须尝试的无代码应用

无代码软件让任何人无需了解编程语言即可构建产品、网站和应用程序。Editor XWix 发布了Editor X&#xff0c;这是一款无需编写任何 CSS &#xff08;层叠样式表&#xff09;或 HTML&#xff08;超文本标记语言&#xff09;代码的新型拖放式网站构建器&#xff0c;为设计师和机…

如何把可观测需求落地为业务大盘?

2022 年 9 月 28 日&#xff0c;阿里云用户组&#xff08;AUG&#xff09;第 11 期活动在深圳举办。活动现场&#xff0c;阿里云技术专家李加贝向参会企业代表分享了如何把可观测需求落地为业务大盘的议题。本文根据现场分享内容整理而成。 为什么需要 Grafana&#xff1f; 演…

智能合约Smart Contract技术详解

文章目录合约编写基本介绍构造方法ipfsmint提现白名单合约前端部署验证合约代码前端和合约交互准备工作获取已经mint了的数量mint合约编写 建议读者先了解下solidity&#xff0c;这里推荐CryptoZombies&#xff0c;还是比较详细的。 ok当你大概知道自己在做什么之后&#xff0…

【概率论】期末复习笔记:假设检验

假设检验目录一、假设检验的基本概念1. 假设检验的基本原理2. 两类错误3. 假设检验的一般步骤4. ppp值二、正态总体参数的假设检验σ2已知&#xff0c;检验μ与μ0的关系\color{dodgerblue}\sigma^2\text{已知&#xff0c;检验}\mu\text{与}\mu_0\text{的关系}σ2已知&#xff…

上海华清远见

解析设备树节点信息实例1获取属性数值实例2获取u32类型的值将获取到的u32类型的值存放在array数组中