动态分区分配算法

一、实验环境

编译软件:pycharm

程序语言:python

二、问题描述:

        设计程序模拟四种动态分区分配算法:首次适应算法、循环首次适应算法、最佳适应算法和最坏适应算法的工作过程。假设内存中空闲分区个数为n,空闲分区大小分别为P1, … ,Pn,在动态分区分配过程中需要分配的进程个数为m(m≤n),它们需要的分区大小分别为S1, … ,Sm,分别利用四种动态分区分配算法将m个进程放入n个空闲分区,给出进程在空闲分区中的分配情况。

三、程序要求:

1)利用首次适应算法、循环首次适应算法、最佳适应算法和最坏适应算法四种动态分区分配算法模拟分区分配过程。

2)模拟四种算法的分区分配过程,给出每种算法进程在空闲分区中的分配情况。

3)输入:空闲分区个数n,空闲分区大小P1, … ,Pn,进程个数m,进程需要的分区大小S1, … ,Sm,算法选择1-首次适应算法,2-循环首次适应算法,3-最佳适应算法,4-最坏适应算法。

4)输出:最终内存空闲分区的分配情况。

四、实现提示:

页面置换的实现过程如下:

  • 变量初始化;
  • 空闲分区个数n,空闲分区大小P1, … ,Pn,进程个数m,进程需要的分区大小S1, … ,Sm,算法选择1-首次适应算法,2-循环首次适应算法,3-最佳适应算法,4-最坏适应算法;
  • 根据用户选择的算法进行动态分区分配;输出所有进程分配后的空闲分区分配情况。

五、代码设计与实现

(一)程序设计

(1)首次适应算法

设计思想:

  1. 首先,对n个空闲分区按地址递增的次序排列;
  2. 在分配内存时,从链首开始顺序查找,直至找到一个大小能满足要求的空闲分区为止;
  3. 按照作业的大小,从该分区中划出一块内存空间,分配给请求者,余下的空闲分区仍留在空闲链中;
  4. 若从链首直至链尾都不能找到一个能满足要求的分区,则表明系统中已没有足够大的内存分配给该进程,内存分配失败,返回。

部分代码:

def first_fit_algorithm(n, free_partitions, m, processes):

    allocated_partitions = [-1] * m#初始化m个作业未分配状态

    # 对空闲分区按照大小由小到大排序

    sorted_partitions = sorted(enumerate(free_partitions), key=lambda x: x[1])

    #排序后将空闲分区按顺序重新编号

    modified_list = [(i, size) for i, (old_idx, size) in enumerate(sorted_partitions)]

    for i in range(m):

        for j, partition_size in modified_list:

            if partition_size >= processes[i]:#当空闲分区的大小大于等于作业大小时,可分配

                allocated_partitions[i] = j

                modified_list[j]=list(modified_list[j])

                modified_list[j][1]-=processes[i]

                break

    return allocated_partitions
(2)循环首次适应算法

设计思想:

  1. 设置一起始查寻指针,用于指示下一次起始查询的空闲分区;
  2. 采用循环查找方式,如果最后一个空闲分区的大小不能满足要求,则返回第一个空闲分区,比较其大小是否满足要求。
  3. 找到后,调整起始查寻指针,从该指针开始继续查询。

部分代码:

def next_fit_algorithm(n, free_partitions, m, processes):
    allocated_partitions = [-1] * m
    j = 0
    for i in range(m):
        while j < n:
            # 寻找下一个合适的空闲分区
            if free_partitions[j] >= processes[i]:
                allocated_partitions[i] = j
                free_partitions[j] -= processes[i]
                break
            j = (j + 1) % n#循环查找匹配的空闲分区

    return allocated_partitions
(3)最佳适应算法

设计思想:

  1. 设将所有的空闲分区按其容量以从小到大的顺序形成一个空闲分区链;
  2. 每次为作业分配内存时,总是把满足要求、又是最小的空闲分区分配给作业。

部分代码:

def best_fit_algorithm(n, free_partitions, m, processes):

    allocated_partitions = [-1] * m



    for i in range(m):

        best_fit_index = -1

        for j in range(n):

            # 寻找最小的适合空闲分区

            if free_partitions[j] >= processes[i]:

                if best_fit_index == -1 or free_partitions[j] < free_partitions[best_fit_index]:

                    best_fit_index = j

        if best_fit_index != -1:

            allocated_partitions[i] = best_fit_index

            free_partitions[best_fit_index] -= processes[i]

    return allocated_partitions
(4)最坏适应算法

设计思想:

  1. 将所有的空闲分区按其容量以从大到小的顺序形成一个空闲分区链,查找时只要看第一个分区能否满足作业要求即可;
  2. 扫描整个空闲分区表或链表时,总是挑选一个最大的空闲区,从中分割一部分存储空间给作业使用。

部分代码:

def worst_fit_algorithm(n, free_partitions, m, processes):

    allocated_partitions = [-1] * m



    for i in range(m):

        worst_fit_index = -1

        for j in range(n):

            # 寻找最大的适合空闲分区

            if free_partitions[j] >= processes[i]:

                if worst_fit_index == -1 or free_partitions[j] > free_partitions[worst_fit_index]:

                    worst_fit_index = j



        if worst_fit_index != -1:

            allocated_partitions[i] = worst_fit_index

            free_partitions[worst_fit_index] -= processes[i]



    return allocated_partitions
(5)源代码
#首次适应算法
#输入:n个空闲分区free_partitions m个作业processes
def first_fit_algorithm(n, free_partitions, m, processes):
    allocated_partitions = [-1] * m#初始化m个作业未分配状态
    # 对空闲分区按照大小由小到大排序
    sorted_partitions = sorted(enumerate(free_partitions), key=lambda x: x[1])
    #排序后将空闲分区按顺序重新编号
    modified_list = [(i, size) for i, (old_idx, size) in enumerate(sorted_partitions)]
    for i in range(m):
        for j, partition_size in modified_list:
            if partition_size >= processes[i]:#当空闲分区的大小大于等于作业大小时,可分配
                allocated_partitions[i] = j
                modified_list[j]=list(modified_list[j])
                modified_list[j][1]-=processes[i]
                free_partitions[i] = modified_list[j][1]
                break
    return allocated_partitions

#循环首次适应算法
def next_fit_algorithm(n, free_partitions, m, processes):
    allocated_partitions = [-1] * m
    j = 0

    for i in range(m):
        while j < n:
            # 寻找下一个合适的空闲分区
            if free_partitions[j] >= processes[i]:
                allocated_partitions[i] = j
                free_partitions[j] -= processes[i]
                break

            j = (j + 1) % n#循环查找匹配的空闲分区

    return allocated_partitions


def best_fit_algorithm(n, free_partitions, m, processes):
    allocated_partitions = [-1] * m

    for i in range(m):
        best_fit_index = -1
        for j in range(n):
            # 寻找最小的适合空闲分区
            if free_partitions[j] >= processes[i]:
                if best_fit_index == -1 or free_partitions[j] < free_partitions[best_fit_index]:
                    best_fit_index = j
        if best_fit_index != -1:
            allocated_partitions[i] = best_fit_index
            free_partitions[best_fit_index] -= processes[i]

    return allocated_partitions


def worst_fit_algorithm(n, free_partitions, m, processes):
    allocated_partitions = [-1] * m

    for i in range(m):
        worst_fit_index = -1
        for j in range(n):
            # 寻找最大的适合空闲分区
            if free_partitions[j] >= processes[i]:
                if worst_fit_index == -1 or free_partitions[j] > free_partitions[worst_fit_index]:
                    worst_fit_index = j

        if worst_fit_index != -1:
            allocated_partitions[i] = worst_fit_index
            free_partitions[worst_fit_index] -= processes[i]

    return allocated_partitions


def print_allocation(free_partitions,allocated_partitions):
    for i, partition in enumerate(allocated_partitions):
        if partition != -1:
            print(f"Process {i+1} allocated to Partition {partition+1}")
        else:
            print(f"Process {i+1} cannot be allocated")
    for i,size in enumerate(free_partitions):
        print(f"partitions {i+1} unallocated {size}KB")



def main():
    # 用户输入空闲分区数量
    n = int(input("Enter the number of free partitions: "))
    # 用户输入每个空闲分区的大小
    free_partitions = [int(input(f"Enter size of Partition {i+1}: ")) for i in range(n)]

    # 用户输入进程数量
    m = int(input("Enter the number of processes: "))
    # 用户输入每个进程的大小
    processes = [int(input(f"Enter size of Process {i+1}: ")) for i in range(m)]

    # 用户选择要使用的算法
    algorithm_choice = int(input("Choose algorithm (1-First Fit, 2-Next Fit, 3-Best Fit, 4-Worst Fit): "))

    # 根据用户选择的算法进行分区分配
    if algorithm_choice == 1:
        allocated_partitions = first_fit_algorithm(n, free_partitions, m, processes)
    elif algorithm_choice == 2:
        allocated_partitions = next_fit_algorithm(n, free_partitions, m, processes)
    elif algorithm_choice == 3:
        allocated_partitions = best_fit_algorithm(n, free_partitions, m, processes)
    elif algorithm_choice == 4:
        allocated_partitions = worst_fit_algorithm(n, free_partitions, m, processes)
    else:
        print("Invalid choice. Please choose a number between 1 and 4.")
        return

    # 输出最终的分区分配情况
    print("\nAllocation Result:")
    print_allocation(allocated_partitions)

if __name__ == "__main__":
    main()

(二)运行结果

以下实验结果经检查均为正确结果。

实例1:首次适应算法:

(1)输入:

(2)输出:

实例2:循环首次适应算法

(1)输入

(2)输出

实例3:最佳适应算法

(1)输入

(2)输出

实例4:最坏适应算法

(1)输入

(2)输出

六、总结

1.在首次适应算法设计过程中,注意到首先需要对空闲分区进行排序,该算法倾向于优先利用低地址部分,保留了高地址部分的大空闲区,留下许多难以利用的碎片。

2.循环首次适应算法在首次适应算法的基础上,将从头检索改为从上一个分区块开始检索,通过实验看出这样做的好处就是使空闲分区分布得更均匀。

3.在最佳适应算法实验过后,发现对分区每次分配后剩余部分很小,形成了许多难以利用的碎片。

4.在最坏适应算法之后,该算法查找效率较高,实验发现其剩余的空闲区不是特别小,产生碎片的可能性小。

Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐