主要参考链接:
动态分区分配:
https://blog.csdn.net/houchaoqun_xmu/article/details/55541299
https://blog.csdn.net/cm_cyj_1116/article/details/53518790
1.进程调度算法FCFS和RR
2.作业调度算法SJF,HRRN
个人感想:动态分区分配和另外两个有点不一样,一开始看到的时候对它的数据结构有点懵。
主要的数据结构(内存空闲分区的地址直接用数组顺序存储了,地址大小顺序按照数组下标
#define MAXNUMBER 100
static int MinPartitionNum;//事先规定的不再切割的剩余分区的大小
static int PartitionNum; //内存中空闲分区的个数
static int ProcessNum; //需要分配的进程个数
static int FreePartition[MAXNUMBER]; //空闲分区对应的内存
static int ProcessNeed[MAXNUMBER]; //需要分配的进程大小
static int LeftFreePartition[MAXNUMBER];
//static int LeftProcessNeed[MAXNUMBER];//参考链接有这个,但我不知道什么来的就没要它了
static char ProcessName[MAXNUMBER];
static char NameProcessToPartition[MAXNUMBER][MAXNUMBER];
struct free_node//这个用在BestFit算法里
{
int partitionSize;
int id;
};
用到的函数
void readDataFunction();//向文本读入数据
void initial();//初始化
void FirstFit();
void BestFit();
void sort(free_node *p,int PartitionNum);//BestFit所需要的排序
void display();//显示最终结果
void display_sort(free_node *p,int PartitionNum);//具体显示BestFit的排序
void display_insert(); //显示输入的数据
核心算法
void FirstFit()
{
printf("***********首次适应算法***********\n");
initial();
display_insert();
int i,j;
for (i = 0;i<ProcessNum;i++) //逐个遍历每个进程
{
for (j = 0;j<PartitionNum;j++) //每次都从分区的首地址开始查找
{
if (ProcessNeed[i] <= (LeftFreePartition[j]-MinPartitionNum) && LeftFreePartition!=0) //进程需要的资源要<=空闲分区大小-事先规定的不再切割的剩余分区的大小
{
LeftFreePartition[j] -= ProcessNeed[i]; //扣除分配给进程的资源
NameProcessToPartition[i][j] = ProcessName[i]; //存储各个进程所在的分区位置
break; //!!!很重要,一个进程分区完后,应该立即break,进行下一个进程的判断
}
}
}
display();
}
//思想:利用冒泡排序对分区大小进行排序,但不改变原分区的位置
void sort(free_node *p,int PartitionNum)//对内存容量进行从小到大的排序(BestFit要用到的
{
for(int i=0;i<PartitionNum;i++)
for(int j=i+1;j<PartitionNum;j++)
if(p[i].partitionSize>p[j].partitionSize)
{
free_node temp;
temp=p[i];
p[i]=p[j];
p[j]=temp;
}
}
void BestFit()
{
//创建一个结构体,包括分区大小和所对应的id,排序过程中,每改变顺序一次,id随着改变
//关键:每次分配完一个进程的内存大小后,都要重新排序
printf("***********最佳适应算法***********\n");
initial();
display_insert();
int i,j;
free_node best[MAXNUMBER];
for (i = 0;i<PartitionNum;i++)
{
//初始化结构体
best[i].partitionSize = FreePartition[i];
best[i].id = i;
}
for (i = 0;i<ProcessNum;i++)
{
sort(best,PartitionNum);
printf("\n第%d次排序: ",i+1);
display_sort(best,PartitionNum);
for (j = 0;j<PartitionNum;j++)
{
// if (ProcessNeed[i] <= best[j].partitionSize)//没有“剩余分区最小不少于”的限制
if(ProcessNeed[i] <= (best[j].partitionSize-MinPartitionNum) && best[j].partitionSize!=0)
{
best[j].partitionSize -= ProcessNeed[i];
NameProcessToPartition[i][best[j].id] = ProcessName[i];
break;
}
}
LeftFreePartition[best[j].id] = best[j].partitionSize;
}
display();
}
测试数据的输入
源代码
#include<stdio.h>
#include <stdlib.h>
#include<string.h>
#define MAXNUMBER 100
static int MinPartitionNum;//事先规定的不再切割的剩余分区的大小
static int PartitionNum; //内存中空闲分区的个数
static int ProcessNum; //需要分配的进程个数
static int FreePartition[MAXNUMBER]; //空闲分区对应的内存
static int ProcessNeed[MAXNUMBER]; //需要分配的进程大小
static int LeftFreePartition[MAXNUMBER];
//static int LeftProcessNeed[MAXNUMBER];//没要它了
static char ProcessName[MAXNUMBER];
static char NameProcessToPartition[MAXNUMBER][MAXNUMBER];
struct free_node
{
int partitionSize;
int id;
};
void readDataFunction();//向文本读入数据
void initial();//初始化
void FirstFit();
void BestFit();
void sort(free_node *p,int PartitionNum);//BestFit所需要的排序
void display();//显示最终结果
void display_sort(free_node *p,int PartitionNum);//具体显示BestFit的排序
void display_insert(); //显示输入的数据
void readDataFunction(){
FILE *fp;
fp=fopen("data.txt","r");
if(fp==NULL){
exit(EXIT_FAILURE);
}
fscanf(fp,"%d",&MinPartitionNum);
fscanf(fp,"%d",&PartitionNum);
for (int i=0;i<PartitionNum;i++)
{
fscanf(fp,"%d",&FreePartition[i]);
}
fscanf(fp,"%d",&ProcessNum);
for (int i=0;i<ProcessNum;i++)
{
fscanf(fp," %c ",&ProcessName[i]);
}
for (int i=0;i<ProcessNum;i++)
{
fscanf(fp,"%d",&ProcessNeed[i]);
}
}
void initial()
{
readDataFunction(); //读取原始数据
for (int i=0;i<ProcessNum;i++)
{
for (int j =0;j<PartitionNum;j++)
{
NameProcessToPartition[i][j] =NULL;
LeftFreePartition[j] = FreePartition[j];
}
}
}
void display_insert(){
printf("剩余分区最小不少于:%d\n",MinPartitionNum);
printf("需要分配内存的进程名:");
for (int i = 0;i<ProcessNum;i++)
{
printf(" %c ",ProcessName[i]);//仅仅为了输出好看而已
}
printf("\n需要分配内存的进程分区大小:");
for (int i = 0;i<ProcessNum;i++)
{
printf("%2d ",ProcessNeed[i]);
}
printf("\n\n");
printf("输入时的分区序号:");
for (int i = 0;i<PartitionNum;i++)
{
printf("分区%d ",i+1);
}
printf("\n分区大小:");
for (int i = 0;i<PartitionNum;i++)
{
printf(" %2d",FreePartition[i]);
}
}
void FirstFit()
{
printf("***********首次适应算法***********\n");
initial();
display_insert();
int i,j;
for (i = 0;i<ProcessNum;i++) //逐个遍历每个进程
{
for (j = 0;j<PartitionNum;j++) //每次都从分区的首地址开始查找
{
if (ProcessNeed[i] <= (LeftFreePartition[j]-MinPartitionNum) && LeftFreePartition!=0) //当系统内存分区足够大的时候,即分配给进程资源
// if (ProcessNeed[i] <= LeftFreePartition[j] && LeftFreePartition!=0) //当系统内存分区足够大的时候,即分配给进程资源
{
LeftFreePartition[j] -= ProcessNeed[i]; //扣除分配给进程的资源
NameProcessToPartition[i][j] = ProcessName[i]; //存储各个进程所在的分区位置
break; //!!!很重要,一个进程分区完后,应该立即break,进行下一个进程的判断
}
}
}
display();
}
void sort(free_node *p,int PartitionNum)//对内存容量进行从小到大的排序
{
for(int i=0;i<PartitionNum;i++)
for(int j=i+1;j<PartitionNum;j++)
if(p[i].partitionSize>p[j].partitionSize)
{
free_node temp;
temp=p[i];
p[i]=p[j];
p[j]=temp;
}
}
void display_sort(free_node *p,int PartitionNum)
{
for (int i = 0;i<PartitionNum;i++)
{
printf("分区%d ",p[i].id+1);
}
printf("\n分区大小:");
for (int i = 0;i<PartitionNum;i++)
{
printf(" %2d",p[i].partitionSize);
}
}
void BestFit()
{
//思想:利用冒泡排序对分区大小进行排序,但不改变原分区的位置
//创建一个结构体,包括分区大小和所对应的id,排序过程中,每改变顺序一次,id随着改变
//关键:每次分配完一个进程的内存大小后,都要重新排序
printf("***********最佳适应算法***********\n");
initial();
display_insert();
int i,j;
free_node best[MAXNUMBER];
for (i = 0;i<PartitionNum;i++)
{
//初始化结构体
best[i].partitionSize = FreePartition[i];
best[i].id = i;
}
for (i = 0;i<ProcessNum;i++)
{
sort(best,PartitionNum);
printf("\n第%d次排序: ",i+1);
display_sort(best,PartitionNum);
for (j = 0;j<PartitionNum;j++)
{
if(ProcessNeed[i] <= (best[j].partitionSize-MinPartitionNum) && best[j].partitionSize!=0)
{
best[j].partitionSize -= ProcessNeed[i];
NameProcessToPartition[i][best[j].id] = ProcessName[i];
break;
}
}
LeftFreePartition[best[j].id] = best[j].partitionSize;
}
printf("\n");
display();
}
void display()
{
int i;
printf("\n分区序号:");
for (i = 0;i<PartitionNum;i++)
{
printf("分区%d ",i+1);
}
printf("\n分区大小:");
for (i = 0;i<PartitionNum;i++)
{
printf(" %4d ",FreePartition[i]);
}
printf("\n剩余大小:");
for (i = 0;i<PartitionNum;i++)
{
printf(" %4d ",LeftFreePartition[i]);
}
printf("\n分配进程情况:\n");
for (i = 0;i<PartitionNum;i++)
{
for (int j = 0;j<ProcessNum;j++)
{
if (NameProcessToPartition[j][i]!=NULL)
{
printf("%c:--->分区%d\n",NameProcessToPartition[j][i],i+1);
}
}
}
printf("\n***************结束***************\n");
}
int main(void){
int a;
printf("动态分区分配算法:1.FirstFit 2.BestFit 3.quit\n");
scanf("%d",&a);
while(a!=3){
switch(a){
case 1:
FirstFit();
break;
case 2:
BestFit();
break;
case 3:
printf("end.\n");
default:
break;
}
// system("cls");
printf("\n动态分区分配算法:1.FirstFit 2.BestFit 3.quit\n");
scanf("%d",&a);
}
return 0;
}
实验截图
FirstFit的结果
BestFit的结果