操作系统--动态分区分配算法模拟

算法原理

  • 首次适应算法 :该算法从空闲分区链首开始查找,直至找到一个能满足其大小要求的空闲分区为止。然后再按照作业的大小,从该分区中划出一块内存分配给请求者,余下的空闲分区仍留在空闲分区链中。
  • 内存回收: 主要在广义上介绍回收方法,而不拘泥于细节。随着系统的运行,内存会逐渐被消耗,而内存主要占用的部分有两个,分别是高速缓存以及用户进程,内核高速缓存包括磁盘高速缓存,slab缓存等。

算法实现序列
假设初始状态下可用的内存空间为640KB,并有下列请求序列:

实验进程
作业1申请130KB。
作业2申请60KB。
作业3申请100KB。
作业2释放60KB。
作业4申请200KB。
作业3释放100KB。
作业1释放130KB
作业5申请140KB。
作业6申请60KB。
作业7申请50KB
作业6释放60KB。

实现代码:

class Block:
    def __init__(self, sid, start, size, status, jobname):
        self.sid = sid
        # 分区号sid
        self.start = start
        # 分区起始地址start
        self.size = size
        # 分区大小size
        self.status = status
        # 分区状态status,e-空闲,1-已分配
        self.jobname = jobname  # 进程名jobname,使用分区的进程名(作业名)


BlockList = []  # 分区表
block_num = 0  # 分区号,初始为e,分区分配则增加1,回收分区则减1


# 分区分配jobname-作业名,jobsize-作业大小
def allocation(jobname, jobsize):
    for b in BlockList:
        # 空闲分区大小与作业大小相等,直接修改分区状态为1,作业名设置为jobname的值
        if b.size == jobsize and b.status == 0:
            b.status = 1
            b.jobname = jobname
            break
            # 空闲分区大小大于作业大小,当前空闲分区分割成2部分:前半部分为被作业占有的分区,后半部分为剩余空闲分区
        if b.size > jobsize and b.status == 0:
            pos = BlockList.index(b)  # 获取当前空闲分区在分区表里的位置
            global block_num
            block_num = block_num + 1  # 分区号增加
            b1 = Block(block_num, b.start + jobsize, b.size - jobsize, 0, ' ')  # 分割后的剩余空闲分区"
            BlockList.insert(pos + 1, b1)  # 剩余空闲分区插入到分区表中,即原分区后增加
            b.status = 1  # 当前分区状态设置为1
            b.size = jobsize  # 当前分区大小设置为作业大小
            b.jobname = jobname  # 当前分区的作业名设置为jobname
            break
    BlockList.sort(key=lambda b: b.start)  # 按分区起始地址排序


# 回收分区
def recycle(sid):
    # 明确回收分区在分区表中的位置pos
    pos = -1
    flag = False  # 前无空闲后无空闲标记
    for b in BlockList:
        if b.sid == sid:
            pos = BlockList.index(b)
    if pos < 0:
        print('无此分区')
        return
    #
    b1 = BlockList[pos]  # 获取回收分区的分区信息#不是第一分区且前一分区为空闲分区
    if pos > 0 and BlockList[pos - 1].status == 0:
        BlockList[pos - 1].size += b1.size  # 前一空闲分区大小增加回收分区的大小
        flag = True  # 改变标记,表明此时回收分区已和前一空闲分区合并,也可以表明该回收分区前有空闲#不是最后分区且后一分区为空闲分区
    if pos < len(BlockList) - 1 and BlockList[pos + 1].status == 0:
        if flag is True:  # 回收分区已和前一空闲分区合并的情况,需判断其后一分区是否空闲
            BlockList[pos - 1].size += BlockList[pos + 1].size  # 将回收分区的后空闲分区合并到回收分区的前空闲分区
            BlockList.remove(BlockList[pos + 1])  # 移除回收分区的后空闲分区,因为已被合并
        else:  # 回收分区未和前一空闲分区合并的情况,需判断其后一分区是否空闲
            BlockList[pos + 1].size += b1.size  # 后一空闲分区大小增加回收分区的大小
            BlockList[pos + 1].start = b1.start  # 后一空闲分区起始地址设为回收分区的起始地址
        flag = True  # 改变标记,表明此时回收分区己和后一空闲分区合并,也可以表明该回收分区后有空闲
    if not flag:  # 前无空闲后无空闲
        b1.status = 0  # 直接修改空闲区状态
        b1.jobname = ' '  # 清空进程名
        return
    BlockList.remove(b1)  # 移除回收分区


# 输出信息
def printinfo():
    s = "{0:7}{1:7}{2:7}{3:7}{4:7}".format('分区号', '起始地址', '分区大小', '分区状态', '占有分区的作业名')
    print(s)
    for b in BlockList:
        if b.jobname == '':
            j = '/ '
        else:
            j = b.jobname
        if b.status == 0:
            s = "{0:^10}{1:^10}{2:^10}{3:^10}{4:^10}".format(b.sid, b.start, b.size, '空闲', j)
            print(s)
        if b.status == 1:
            s = "{0:^10}{1:^10}{2:^10}{3:^10}{4:^10}".format(b.sid, b.start, b.size, '已分配', j)
            print(s)


if __name__ == '__main__':
    b = Block(block_num, 0, 640, 0, '')  # 初始空闲分区640
    BlockList.append(b)
    print('初始空间情况')
    printinfo()
    print('---------------------------------------------------------')
    allocation('J1', 130)
    allocation('J2', 60)
    allocation('J3', 100)
    print('J1-J3三个作业的分区分配情况(J1-130KB,J2-60KB,J3-100KB)')
    printinfo()
    print('---------------------------------------------------------')
    recycle(1)
    print('回收分区1')
    printinfo()
    print('---------------------------------------------------------')
    allocation('J4', 200)
    print('作业J4分区分配情况(J4-200KB)')
    printinfo()
    print('---------------------------------------------------------')
    recycle(2)
    print('回收分区2')
    printinfo()
    print('---------------------------------------------------------')
    recycle(0)
    print('回收分区0')
    printinfo()
    print('---------------------------------------------------------')
    allocation('J5', 140)
    print('作业J5分区分配情况(J5-140KB)')
    printinfo()
    # print('---------------------------------------------------------')
    # recycle(3)
    # print('回收分区3')
    # printinfo()
    print('---------------------------------------------------------')
    allocation('J6', 60)
    print('作业J6分区分配情况(J6-60KB)')
    printinfo()
    print('---------------------------------------------------------')
    allocation('J7', 50)
    print('作业J7分区分配情况(J7-50KB)')
    printinfo()
    print('---------------------------------------------------------')
    recycle(5)
    print('回收分区5')
    printinfo()
    print('---------------------------------------------------------')

实现结果:
在这里插入图片描述
转载此博客请注明来源,谢谢

  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

喵星人来踩博客

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

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

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

打赏作者

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

抵扣说明:

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

余额充值