存储管理分区分配算法
分区存储管理

1、单用户连续分区存储管理
单一连续分区:把内存储器分为两个区,一个分区固定分配给操 作系统使用,另一个分配给用户使用,称作“用户区” 系统特点:1、系统总是把整个用户区分配给一个用户使用 2、内存用户区又被分为“使用区”和“空闲区”两部分 3、当作业被调度时就获得全部空间 4、作业运行完后,全部主存空间又恢复成空闲(以上所指 的全部主存空间是全部用户区空间) 对于连续区分配而言,虽然这种管理方案不需要专门的硬件,但是应 有硬件保护机构,以确保用户程序不至于偶然或无意地干扰系统区中 的信息 使用界限寄存器的方法。界限寄存器中存放用户程序的起始地址 和终止地址,作业运行时,检查访问指令或数据的地址,若不在界限 寄存器所框住的范围内,则发生越界中断。
分
区 1 2 3 4
号
起 始 地 址 20KB 28KB 60KB 124KB
长 8KB 32KB 64KB
度
使 用 标 志 作业1 作业6 0 作业2
132KB
地址重定位与存储保护
在采用固定分区存储管理这种存储管理方式时,应该对程序实行静态 重定位。不仅要防止用户程序对操作系统形成的侵扰,也要防止用户程序 与用户程序之间形成的侵扰。因此必须在CPU中设置一对专用的寄存器,用 于存储保护。
3、可变分区存储管理
内存的分配:内存不是预先划分好的,而是当作业装入时,根据作业的需求和内 存空间的使用情况来决定是否分配。若有足够的空间,则按需要分割与作业相对 地址空间同样大小分区给该进程;否则令其等待主存空间
最先适应算法
最佳适应算法
最坏ቤተ መጻሕፍቲ ባይዱ应算法
2、固定分区存储管理
“固定分区”存储管理的基本思想:预先把内存储器中可供分配的 用户区事先划分成若干个连续的分区,每个分区的尺寸可以相同, 也可以不同。划分后,内存储器中分区的个数以及每个分区的位置、 尺寸保持不变。每个分区中只允许装入一个作业运行。
存储管理动态分区分配及回收算法

存储管理动态分区分配及回收算法存储管理是计算机系统中的重要组成部分,它负责管理和分配计算机中的物理内存资源。
在计算机系统中,通过动态分区分配和回收算法来实现对这些资源的有效利用。
本文将介绍动态分区分配和回收算法的原理、主要算法以及优缺点。
动态分区分配是一种灵活、动态的内存分配方式,它根据进程的需求动态地分配内存空间。
动态分区分配算法有多种,其中最常用的有首次适应算法、最佳适应算法和最坏适应算法。
首次适应算法(First Fit)是最常用的分配算法之一、它从低地址开始寻找第一个满足要求的空闲分区来分配进程。
这种算法的优点是简单、高效,但是可能会产生大量的碎片空间,降低内存的利用率。
最佳适应算法(Best Fit)是在所有空闲分区中找到一个大小最适合进程的分区来分配。
它的主要思想是选择一个更接近进程大小的空闲分区,以减少碎片空间的产生。
然而,这种算法的缺点是需要遍历整个空闲分区链表,因此效率相对较低。
最坏适应算法(Worst Fit)与最佳适应算法相反,它选择一个大小最大的空闲分区来分配进程。
这种算法的好处是可以尽可能地保留大块的碎片空间,以便后续分配使用。
但是,它也会导致更多的碎片空间浪费。
动态分区的回收算法是用于回收被释放的内存空间并合并相邻的空闲分区,以尽量减少碎片空间的产生。
常见的回收算法有合并相邻空闲分区算法和快速回收算法。
合并相邻空闲分区算法会在每次有分区被回收时,检查是否有相邻的空闲分区可以合并。
如果有,就将它们合并为一个大的空闲分区。
这样可以最大程度地减少碎片空间,提高内存的利用效率。
快速回收算法是一种将被释放的分区插入到一个空闲分区链表的头部,而不是按照地址顺序进行插入的算法。
这样可以减少对整个空闲分区链表的遍历时间,提高回收的效率。
总结起来,动态分区分配和回收算法在存储管理中起着重要的作用。
首次适应算法、最佳适应算法和最坏适应算法是常用的动态分区分配算法,它们各自有着不同的优缺点。
可变分区存储管理的内存分配算法模拟实现----最佳适应算法

可变分区存储管理的内存分配算法模拟实现----最佳适应算法可变分区存储管理是一种内存管理技术,其通过将内存分割成不同大小的区域来存储进程。
每个进程被分配到与其大小最匹配的区域中。
内存分配算法的选择影响了系统的性能和资源利用率。
本文将介绍最佳适应算法,并模拟实现该算法。
一、什么是最佳适应算法?最佳适应算法是一种可变分区存储管理中的内存分配策略。
它的基本思想是在每次内存分配时选择最合适的空闲区域。
具体来说,它从可用的空闲区域中选择大小与需要分配给进程的内存最接近的区域。
二、算法实现思路最佳适应算法实现的关键是如何快速找到最合适的空闲区域。
下面给出一个模拟实现的思路:1. 初始化内存分区列表,首先将整个内存定义为一个大的空闲区域。
2. 当一个进程请求分配内存时,从列表中找到与所需内存最接近的空闲区域。
3. 将该空闲区域分割成两部分,一部分分配给进程,并将该部分标记为已分配,另一部分留作新的空闲区域。
4. 更新内存分区列表。
5. 当一个进程释放内存时,将其所占用的内存区域标记为空闲,然后尝试合并相邻的空闲区域。
三、算法模拟实现下面是一个简单的Python代码实现最佳适应算法:pythonclass MemoryPartition:def __init__(self, start_addr, end_addr, is_allocated=False): self.start_addr = start_addrself.end_addr = end_addrself.is_allocated = is_allocatedclass MemoryManager:def __init__(self, total_memory):self.total_memory = total_memoryself.partition_list = [MemoryPartition(0, total_memory)]def allocate_memory(self, process_size):best_fit_partition = Nonesmallest_size = float('inf')# 找到最佳适应的空闲区域for partition in self.partition_list:if not partition.is_allocated and partition.end_addr - partition.start_addr >= process_size:if partition.end_addr - partition.start_addr < smallest_size:best_fit_partition = partitionsmallest_size = partition.end_addr - partition.start_addrif best_fit_partition:# 将空闲区域分割,并标记为已分配new_partition =MemoryPartition(best_fit_partition.start_addr,best_fit_partition.start_addr + process_size, True)best_fit_partition.start_addr += process_sizeself.partition_list.append(new_partition)return new_partition.start_addr,new_partition.end_addrelse:return -1, -1def deallocate_memory(self, start_addr, end_addr):for partition in self.partition_list:if partition.start_addr == end_addr and not partition.is_allocated:# 标记空闲区域partition.is_allocated = False# 尝试合并相邻空闲区域for next_partition in self.partition_list:if not next_partition.is_allocated andnext_partition.start_addr == end_addr:end_addr = next_partition.end_addrself.partition_list.remove(next_partition)breakelse:breakdef print_partitions(self):for partition in self.partition_list:if partition.is_allocated:print(f"Allocated Partition: {partition.start_addr} - {partition.end_addr}")else:print(f"Free Partition: {partition.start_addr} - {partition.end_addr}")# 测试最佳适应算法if __name__ == "__main__":mm = MemoryManager(1024)start, end = mm.allocate_memory(256)print(f"Allocated memory: {start} - {end}")mm.print_partitions()mm.deallocate_memory(start, end)print("Memory deallocated:")mm.print_partitions()以上代码实现了一个简单的内存管理器类`MemoryManager`,它具有`allocate_memory`和`deallocate_memory`等方法。
在可变分区存储管理中,最优适应分配算法

在可变分区存储管理中,最优适应分配算法
最优适应分配算法(optimal fit algorithm)是可变分区存储管理中常用的算法,它是以一种有效而实用方式来利用磁盘存储空间的技术,目的是使用最小的空间来存放最多的文件。
一、算法简介
最优适应分配算法是在可变分区存储管理系统中应用最多的一种有效算法。
它通过寻找和利用未被利用的空间,有效地管理存储空间,减少内存的浪费。
此算法的基本原理是比较进程的内存空间需求和当前空闲分区的剩余空间,选择一个空闲分区分配给进程,使得分配的这块空间刚好能够满足进程的内存空间需求。
二、算法的优势
1、空间利用率高:最优适应分配算法做了色样的优化,通过对比空闲区和进程大小,可以在多个空闲区中选择一个最合适的空间来分配,这就有效地将空闲分区完全利用起来。
2、降低内存碎片:最优适应分配算法在进行存储空间的分配时,给每一个进程的存储空间要求满足有效利用完可用的空闲分区,这样就可以有效地降低内存碎片的影响。
3、处理时间短暂:最优适应分配算法虽然空间利用率高,但是相对地,其耗费的时间是少的,因此,这种算法可以满足时间要求,确保效率。
三、应用情况
最优适应分配算法主要用于可变分区存储管理技术,这种技术可以有效地管理大量文件,而不会浪费空间。
而且现在,这种算法已经被广泛应用于嵌入式系统中,专家们尤其是在嵌入式系统设计中广泛地使用最优适应分配算法,以在CPU装入的程序数量、运行程序数量不变的情况下,达到最大的利用空间效果。
操作系统-动态分区分配算法实验报告

实验题目:存储器内存分配设计思路:1.既然是要对内存进行操作,首先对和内存相关的内容进行设置我使用的是用自定义的数据结构struct来存放内存中一个内存块的内容包括:始地址、大小、状态(f:空闲u:使用e:结束)之后采用数组来存放自定义的数据类型,这样前期的准备工作就完成了2.有了要加工的数据,接下来定义并实现了存放自定义数据类型的数组的初始化函数和显示函数,需要显示的是每个内存块的块号、始地址、大小、状态3.接着依此定义三种动态分区分配算法首次适应算法、最佳适应算法和最差适应算法4.对定义的三种算法逐一进行实现①首次适应算法:通过遍历存放自定义数据类型的数组,找到遍历过程中第一个满足分配大小的内存块块号i,找到之后停止对数组的遍历,将i之后的块号逐个向后移动一个,然后将满足分配大小的内存块i分为两块,分别是第i块和第i+1块,将两块的始地址、大小、状态分别更新,这样便实现了首次适应算法②最佳适应算法:和首次适应算法一样,首先遍历存放自定义数据类型的数组,找到满足分配大小的内存块后,对内存块的大小进行缓存,因为最佳适应是要找到最接近要分配内存块大小的块,所以需要遍历整个数组,进而找到满足分配大小要求的而且碎片最小的块i,之后的操作和首次遍历算法相同③最差适应算法:和最佳适应算法一样,区别在于,最佳适应是找到最接近要分配内存块大小的块,而最差适应是要找到在数组中,内存最大的块i,找到之后的操作和最佳适应算法相同,因此不在这里赘述。
5.定义并实现释放内存的函数通过块号找到要释放的内存块,把要释放的内存块状态设置成为空闲,查看要释放的块的左右两侧块的状态是否为空闲,如果有空闲,则将空闲的块和要释放的块进行合并(通过改变块的始地址、大小、状态的方式)6.定义主函数,用switch来区分用户需要的操作,分别是:①首次适应②最佳适应③最差适应④释放内存⑤显示内存⑥退出系统实验源程序加注释:#include<bits/stdc++.h>#define MI_SIZE 100 //内存大小100typedef struct MemoryInfomation//一个内存块{int start; //始地址int Size; //大小char status; //状态 f:空闲 u:使用 e:结束} MI;MI MList[MI_SIZE];void InitMList() //初始化{int i;MI temp = { 0,0,'e' };for (i = 0; i < MI_SIZE; i++){MList[i] = temp;}MList[0].start = 0; //起始为0MList[0].Size = MI_SIZE;//大小起始最大MList[0].status = 'f'; //状态起始空闲}void Display() //显示{int i, used = 0;printf("\n---------------------------------------------------\n");printf("%5s%15s%15s%15s", "块号", "始地址", "大小", "状态");printf("\n---------------------------------------------------\n");for (i = 0; i < MI_SIZE && MList[i].status != 'e'; i++){if (MList[i].status == 'u'){used += MList[i].Size;}printf("%5d%15d%15d%15s\n", i, MList[i].start, MList[i].Size, MList[i].status == 'u' ? "使用" : "空闲");}printf("\n----------------------------------------------\n");}void FirstFit(){int i, j, flag = 0;int request;printf("最先适应算法:请问你要分配多大的内存\n");scanf("%d", &request);for (i = 0; i < MI_SIZE && MList[i].status != 'e'; i++){if (MList[i].Size >= request && MList[i].status == 'f') {if (MList[i].Size - request <= 0){MList[i].status = 'u';}else{for (j = MI_SIZE - 2; j > i; j--){MList[j + 1] = MList[j];}MList[i + 1].start = MList[i].start + request; MList[i + 1].Size = MList[i].Size - request;MList[i + 1].status = 'f';MList[i].Size = request;MList[i].status = 'u';flag = 1;}break;}}if (flag != 1 || i == MI_SIZE || MList[i].status == 'e'){printf("没有足够大小的空间分配\n");}Display();}void BadFit(){int i, j = 0, k = 0, flag = 0, request;printf("最坏适应算法:请问你要分配多大的内存\n");scanf("%d", &request);for (i = 0;i < MI_SIZE - 1 && MList[i].status != 'e';i++){if (MList[i].Size >= request && MList[i].status == 'f') {flag = 1;if (MList[i].Size > k){k = MList[i].Size;j = i;}}}i = j;if (flag == 0){printf("没有足够大小的空间分配\n");j = i;}else if (MList[i].Size - request <= 0){MList[i].status = 'u';}else{for (j = MI_SIZE - 2;j > i;j--){MList[j + 1] = MList[j];}MList[i + 1].start = MList[i].start + request;MList[i + 1].Size = MList[i].Size - request;MList[i + 1].status = 'f';MList[i].Size = request;MList[i].status = 'u';}Display();}void M_Release() //释放内存{int i, number;printf("\n请问你要释放哪一块内存:\n");scanf("%d", &number);if (MList[number].status == 'u'){MList[number].status = 'f';if (MList[number + 1].status == 'f')//右边空则合并{MList[number].Size += MList[number].Size;for (i = number + 1; i < MI_SIZE - 1 && MList[i].status != 'e'; i++) { //i后面的每一个结点整体后移if (i > 0){MList[i] = MList[i + 1];}}}if (number > 0 && MList[number - 1].status == 'f')//左边空则合并{MList[number - 1].Size += MList[number].Size;for (i = number; i < MI_SIZE - 1 && MList[i].status != 'e'; i++){MList[i] = MList[i + 1];}}}else{printf("该块内存无法正常释放\n");}Display();}void BestFit(){int i, j = 0, t, flag = 0, request;printf("最佳适应算法:请问你要分配多大的内存\n");scanf("%d", &request);t = MI_SIZE;for (i = 0; i < MI_SIZE && MList[i].status != 'e'; i++){if (MList[i].Size >= request && MList[i].status == 'f'){flag = 1;if (MList[i].Size < t){t = MList[i].Size;j = i;}}}i = j;if (flag == 0){printf("没有足够大小的空间分配\n");j = i;}else if (MList[i].Size - request <= 0){MList[i].status = 'u';}else {for (j = MI_SIZE - 2; j > i; j--){MList[j + 1] = MList[j];}MList[i + 1].start = MList[i].start + request;MList[i + 1].Size = MList[i].Size - request;MList[i + 1].status = 'f';MList[i].Size = request;MList[i].status = 'u';}Display();}int main(){int x;InitMList();while (1){printf(" \n"); printf(" 1.首次适应\n");printf(" 2.最佳适应\n");printf(" 3.最差适应\n"); printf(" 4.释放内存\n"); printf(" 5.显示内存\n"); printf(" 6.退出系统\n"); printf("请输入1-6:");scanf("%d", &x);switch (x){case 1:FirstFit();break;case 2:BestFit();break;case 3:BadFit();break;case 4:M_Release();break;case 5:Display();break;case 6:exit(0);}}return 0;}实验测试结果记录:1.首次适应2.最佳适应3.最差适应4.释放内存5.显示内存6.退出系统请输入1-6:1最先适应算法:请问你要分配多大的内存10---------------------------------------------------块号始地址大小状态---------------------------------------------------0 0 10 使用1 10 90 空闲----------------------------------------------1.首次适应2.最佳适应3.最差适应4.释放内存5.显示内存6.退出系统请输入1-6:1最先适应算法:请问你要分配多大的内存25---------------------------------------------------块号始地址大小状态---------------------------------------------------0 0 10 使用1 10 25 使用2 35 65 空闲----------------------------------------------1.首次适应2.最佳适应3.最差适应4.释放内存5.显示内存6.退出系统请输入1-6:1最先适应算法:请问你要分配多大的内存15---------------------------------------------------块号始地址大小状态---------------------------------------------------0 0 10 使用1 10 25 使用2 35 15 使用3 50 50 空闲----------------------------------------------1.首次适应2.最佳适应3.最差适应4.释放内存5.显示内存6.退出系统请输入1-6:1最先适应算法:请问你要分配多大的内存20---------------------------------------------------块号始地址大小状态---------------------------------------------------0 0 10 使用1 10 25 使用2 35 15 使用3 50 20 使用4 70 30 空闲----------------------------------------------1.首次适应2.最佳适应3.最差适应4.释放内存5.显示内存6.退出系统请输入1-6:4请问你要释放哪一块内存:---------------------------------------------------块号始地址大小状态---------------------------------------------------0 0 10 空闲1 10 25 使用2 35 15 使用3 50 20 使用4 70 30 空闲----------------------------------------------1.首次适应2.最佳适应3.最差适应4.释放内存5.显示内存6.退出系统请输入1-6:4请问你要释放哪一块内存:2---------------------------------------------------块号始地址大小状态---------------------------------------------------0 0 10 空闲1 10 25 使用2 35 15 空闲3 50 20 使用4 70 30 空闲----------------------------------------------1.首次适应2.最佳适应3.最差适应4.释放内存5.显示内存6.退出系统请输入1-6:2最佳适应算法:请问你要分配多大的内存5---------------------------------------------------块号始地址大小状态---------------------------------------------------0 0 5 使用1 5 5 空闲2 10 25 使用3 35 15 空闲4 50 20 使用5 70 30 空闲----------------------------------------------1.首次适应2.最佳适应3.最差适应4.释放内存5.显示内存6.退出系统请输入1-6:3最坏适应算法:请问你要分配多大的内存25---------------------------------------------------块号始地址大小状态---------------------------------------------------0 0 5 使用1 5 5 空闲2 10 25 使用3 35 15 空闲4 50 20 使用5 70 25 使用6 95 5 空闲----------------------------------------------1.首次适应2.最佳适应3.最差适应4.释放内存5.显示内存6.退出系统请输入1-6:总结与自评:总结:分区存储管理是操作系统进行内存管理的一种方式。
动态分区管理方式及动态分区算法

动态分区管理方式及动态分区算法一、动态分区概述在操作系统中,内存管理是一个非常重要的部分。
在实际的应用中,程序的内存需求是会发生变化的,因此需要一种灵活的内存管理方式来满足不同程序的内存需求。
动态分区管理方式应运而生,它可以根据程序的需求,灵活地分配和回收内存空间,是一种高效的内存管理方式。
二、动态分区管理方式动态分区管理方式是指将内存划分为多个大小不等的分区,每个分区都可以被分配给进程使用,当进程终止时,分区将被回收。
动态分区管理方式通常通过动态分区算法来实现,下面将介绍几种常见的动态分区算法。
三、首次适应算法首次适应算法是最简单和最直观的动态分区分配算法。
它的基本思想是在空闲分区链表中按照位置区域顺序查找第一个能够满足进程大小需求的空闲分区,并将其分配给进程。
首次适应算法的优点是实现简单,分区利用率较高,但缺点是会产生大量的不连续碎片。
四、最佳适应算法最佳适应算法是在空闲分区链表中查找满足进程大小需求的最小空闲分区,并将其分配给进程。
最佳适应算法的优点是可以减少外部碎片,缺点是查找适合的空闲分区会花费较长的时间。
五、最坏适应算法最坏适应算法是在空闲分区链表中查找满足进程大小需求的最大空闲分区,并将其分配给进程。
最坏适应算法的优点是能够产生较小的碎片,但缺点是会导致剩余分区较多,影响分区利用率。
六、动态分区管理方式的优缺点动态分区管理方式相比于静态分区管理方式有很多优点,比如可以灵活地满足不同程序的内存需求,可以动态地合并和分割分区,提高了内存的利用率等。
但是动态分区管理方式也有一些缺点,比如会产生碎片,分配和回收内存的开销较大等。
七、结语动态分区管理方式及其算法在实际应用中有着广泛的应用,通过合理选择动态分区算法,可以提高内存的利用率,改善系统性能。
也需要注意动态分区管理方式可能产生的碎片问题,可以通过内存紧缩等手段来解决。
希望本文对读者有所帮助。
动态分区管理方式及动态分区算法八、碎片问题与解决方法在动态分区管理方式中,经常会出现碎片问题,包括内部碎片和外部碎片。
存储管理动态分区分配及回收算法

存储管理动态分区分配及回收算法存储管理是操作系统中非常重要的一部分,它负责对计算机系统的内存进行有效的分配和回收。
动态分区分配及回收算法是其中的一种方法,本文将详细介绍该算法的原理和实现。
动态分区分配及回收算法是一种将内存空间划分为若干个动态分区的算法。
当新的作业请求空间时,系统会根据作业的大小来分配一个合适大小的分区,使得作业可以存储在其中。
当作业执行完毕后,该分区又可以被回收,用于存储新的作业。
动态分区分配及回收算法包括以下几个步骤:1.初始分配:当系统启动时,将整个内存空间划分为一个初始分区,该分区可以容纳整个作业。
这个分区是一个连续的内存块,其大小与初始内存大小相同。
2.漏洞表管理:系统会维护一个漏洞表,用于记录所有的可用分区的大小和位置。
当一个分区被占用时,会从漏洞表中删除该分区,并将剩余的空间标记为可用。
3.分区分配:当一个作业请求空间时,系统会根据作业的大小,在漏洞表中查找一个合适大小的分区。
通常有以下几种分配策略:- 首次适应(First Fit): 从漏洞表中找到第一个满足作业大小的分区。
这种策略简单快速,但可能会导致内存碎片的产生。
- 最佳适应(Best Fit): 从漏洞表中找到最小的满足作业大小的分区。
这种策略可以尽量减少内存碎片,但是分配速度相对较慢。
- 最差适应(Worst Fit): 从漏洞表中找到最大的满足作业大小的分区。
这种策略可以尽量减少内存碎片,但是分配速度相对较慢。
4.分区回收:当一个作业执行完毕后,系统会将该分区标记为可用,并更新漏洞表。
如果相邻的可用分区也是可合并的,系统会将它们合并成一个更大的分区。
总结来说,动态分区分配及回收算法是一种对计算机系统内存进行有效分配和回收的方法。
通过合理的分配策略和回收机制,可以充分利用内存资源,提高系统性能。
然而,如何处理内存碎片问题以及选择合适的分配策略是需要仔细考虑的问题。
存储管理首次、最佳、最坏适应算法

最佳适应算法最佳适应算法是从全部空闲区中找出能满足作业要求的、且大小最小的空闲分区的一种计算方法,这种方法能使碎片尽量小。
找到:满足要求的自由分区分配排序:从小到大含义最佳适应算法(Best Fit):它从全部空闲区中找出能满足作业要求的、且大小最小的空闲分区,这种方法能使碎片尽量小。
为适应此算法,空闲分区表(空闲区链)中的空闲分区要按从小到大进行排序,自表头开始查找到第一个满足要求的自由分区分配。
该算法保留大的空闲区,但造成许多小的空闲区。
应用问题Best fit算法等价于装箱问题,举例如下:装箱问题:有体积为V的箱子N个,体积为Vi的物品M个,求使得物品全部能够装入箱子,箱子数量的最小值。
假设 V=6 M=10,V1,V2,...,V10分别为:3 4 4 3 5 1 2 5 3 1。
计算过程如下:第一步按物品体积降序排序:5 5 4 4 3 3 3 2 1 1第二步:取未装箱的最大值5装入第一个箱子。
第三步:判断第一个箱子是否已满,不满且剩余空间为1,搜寻剩下体积小于等于1的物品填入箱子1,箱子1填满。
第四步:重复第二,第三步,直到所有物品装入箱子为止,得到箱子数量为6. 6即时本例N的最小值。
最坏适应算法特点:扫描整个空闲分区或链表优点:可使剩下的空闲分区不至于太小最坏适应算法(worst fit)最坏适应分配算法要扫描整个空闲分区或链表,总是挑选一个最大的空闲分区分割给作业使用。
该算法要求将所有的空闲分区按其容量从大到小的顺序形成一空闲分区链,查找时只要看第一个分区能否满足作业要求。
优点:可使剩下的空闲分区不至于太小,产生碎片的几率最小,对中、小作业有利,同时该算法查找效率很高。
缺点:会使存储器中缺乏大的空闲分区。
首次适应算法首次适应算法从空闲分区表的第一个表目起查找该表,把最先能够满足要求的空闲区分配给作业,这种方法目的在于减少查找时间。
为适应这种算法,空闲分区表(空闲区链)中的空闲分区要按地址由低到高进行排序。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
/*9.3.2 源程序*//***pcb.c***/#include "stdio.h"#include "stdlib.h"#include "string.h"#define MAX 32767typedef struct node /*设置分区描述器*/{int address,size;struct node *next;}RECT;/*函数原型*/RECT *assignment(RECT *head,int application);void acceptment1(RECT *head,RECT *back1);void acceptment2(RECT *head,RECT *back1) ;int backcheck(RECT *head,RECT *back1);void print(RECT *head);/*变量声明*/RECT *head,*back,*assign1,*p;int application1,maxblocknum;char way;/*主函数*/main(){char choose[10];int check;head=malloc(sizeof(RECT)); /*建立可利用区表的初始状态*/p=malloc(sizeof(RECT));head->size=MAX;head->address=0;head->next=p;maxblocknum=1;p->size=MAX;p->address=0;p->next=NULL;print(head); /*输出可利用表初始状态*/printf("Enter the way(best or first(b/f)\n");/*选择适应策略*/ scanf("%c",&way);do{printf("Enter the assign or accept(as/ac)\n");scanf("%s",choose); /*选择分配或回收*/if(strcmp(choose,"as")==0) /*as为分配*/{printf("Input application:\n");scanf("%d",&application1);/*输入申请空间大小*/assign1=assignment(head,application1);/*调用分配函数*/if(assign1->address==-1)/*分配不成功*/printf("Too large application!,assign fails!!\n\n");elseprintf("Success!!ADDRESS=%5d\n",assign1->address); /*分配成功*/print(head); /*输出*/}elseif(strcmp(choose,"ac")==0) /*回收*/{back=malloc(sizeof(RECT));printf("Input Adress and Size!!\n");scanf("%d%d",&back->address,&back->size);/*输入回收地址和大小*/check=backcheck(head,back); /*检查*/if(check==1){if(tolower(way)=='f')/*首先适应算法*/acceptment1(head,back); /*首先适应*/elseacceptment2(head,back);/*最佳适应*/print(head);}}}while(!strcmp(choose,"as")||!strcmp(choose,"ac"));}/*分配函数*/RECT *assignment(RECT *head,int application){RECT *after,*before,*assign;assign=malloc(sizeof(RECT)); /*分配申请空间*/assign->size=application;assign->next=NULL;if(application>head->size||application<=0)assign->address=-1; /*申请无效*/else{before=head;after=head->next;while(after->size<application)/*查找适应的结点*/{before=before->next;after=after->next;}if(after->size==application) /*结点大小等于申请大小则完全分配*/ {if(after->size==head->size)maxblocknum--;before->next=after->next;assign->address=after->address;free(after);}else{if(after->size==head->size) maxblocknum--;after->size=after->size-application; /*大于申请空间则截取相应大小分配*/assign->address=after->address+after->size;if(tolower(way)=='b')/*如果是最佳适应,将截取后剩余结点重新回收到合适位置*/{before->next=after->next;back=after;acceptment2(head,back);}}if(maxblocknum==0) /*修改最大数和头结点值*/{before=head;head->size=0;maxblocknum=1;while(before!=NULL){if(before->size>head->size){head->size=before->size;maxblocknum=1;}elseif(before->size==head->size)maxblocknum++;before=before->next;}}}assign1=assign;return assign1; /*返回分配给用户的地址*/}void acceptment1(RECT *head,RECT *back1)/*首先适应*/{RECT *before,*after;int insert;before=head;after=head->next;insert=0;while(!insert) /*将回收区插入空闲区表*/{if((after==NULL)||((back1->address<=after->address)&&(back1->address>=before->address))){before->next=back1;back1->next=after;insert=1;}else{before=before->next;after=after->next;}}if(back1->address==before->address+before->size)/*与上一块合并*/ {before->size=before->size+back1->size;before->next=back1->next;free(back1);back1=before;}if(after!=NULL&&(after->address==back1->address+back1->size)){ /*与下一块合并*/back1->size=back1->size+after->size;back1->next=after->next;free(after);}if(head->size<back1->size) /*修改最大块值和最大块个数*/{head->size=back1->size;maxblocknum=1;}elseif(head->size==back1->size)maxblocknum++;}/*最佳适应,back1为回收结点的地址*/void acceptment2(RECT *head,RECT *back1){RECT *before,*after;int insert ;insert=0;before=head;after=head->next;if(head->next==NULL) /*如果可利用区表为空*/{head->size=back1->size;head->next=back1;maxblocknum++;back1->next=NULL;}else{while(after!=NULL) /*与上一块合并*/if(back1->address==after->size+after->address){before->next=after->next;back->size=after->size+back1->size;free(after);after=NULL;}else{after=after->next;before=before->next;}before=head;after=head->next;while(after!=NULL)if(after->address==back1->size+back1->address) /*与下一块合并*/ {back1->size=back1->size+after->size;before->next=after->next;free(after);after=NULL;}elsebefore=before->next;after=after->next;}before=head;/*将回收结点插入到合适的位置*/after=head->next;do{if(after==NULL||(after->size>back1->size)){before->next=back1;back1->next=after;insert=1;}else{before=before->next;after=after->next;}}while(!insert);if(head->size<back1->size) /*修改最大块值和最大块数*/{head->size=back1->size;maxblocknum++;}elseif(head->size==back1->size)maxblocknum++;}}void print(RECT *head) /*输出链表*/{RECT *before,*after;int index,k;before=head->next;index=1;if(head->next==NULL)printf("NO part for assignment!!\n");else{printf("*****index*******address********end*********size*****\n"); while(before!=NULL){printf("----------------------------------------------------\n");printf(" %-13d%-13d%-13d%-13d\n",index,before->address,before->ad dress+before->size-1,before->size);printf("----------------------------------------------------\n");index++;before=before->next;}}}/*检查回收块的合法性,back1为要回收的结点地址*/int backcheck(RECT *head,RECT *back1){RECT *before,*after;int check=1;if(back1->address<0||back1->size<0)check=0;/*地址和大小不能为负*/before=head->next;while((before!=NULL)&&check)/*地址不能和空闲区表中结点出现重叠*/ if(((back1->address<before->address)&&(back1->address+back1->size>before->address))||((back1->address>=before->address)&&(back1->address<before->address+before->size)))check=0;elsebefore=before->next;if(check==0)printf("Error input!!\n");return check; /*返回检查结果*/}。