设计一 内存空间的分配和回收
【实验目的】
通过本实验,帮助学生理解存储管理的功能,掌握动态异长分区的存储分配与回收算法。
【实验内容】
模拟动态异长分区的分配算法、回收算法。
【实验要求】
常用的动态异长分区的分配算法有:最先适应算法、最佳适应算法和最坏适应算法。要求选择任意一种算法,设计相应的数据结构,模拟内存空间的分配和回收。实验报告中给出程序中使用的数据结构及流程图。
【实验原理】
- 首次适应算法(First Fit)
该算法从空闲分区链首开始查找,直至找到一个能满足其大小要求的空闲分区为止。然后再按照作业的大小,从该分区中划出一块内存分配给请求者,余下的空闲分区仍留在空闲分区链中。空闲分区以地址递增次序排列。
缺点:低地址部分不断被划分,留下许多难以利用、很小的空闲区,而每次查找又都从低地址部分开始,会增加查找的开销。
优点:开销较小,回收分区一般无需对空闲分区队列重新排序。该算法倾向于使用内存中低地址部分的空闲区,在高地址部分的空闲区很少被利用,从而保留了高地址部分的大空闲区。显然为以后到达的大作业分配大的内存空间创造了条件。
- 最佳适应算法(Best Fit)
该算法总是把既能满足要求,又是最小的空闲分区分配给作业。为了加速查找,该算法要求将所有的空闲区按容量递增顺序排成一个空白链。这样每次找到的第一个满足要求的空闲区,必然是最优的。
缺点:因为每次分配后剩余的空间一定是最小的,所以内存中留下许多难以利用的小的空闲区(外部碎片);开销大,回收后可能要重新排序。
优点:每次分配给文件的都是最合适该文件大小的分区。有更多大分区被保留。
- 最坏适应算法(Worst Fit)
空闲区按容量递减次序排列,每次优先分配最大连续空闲区。
缺点:较大空闲分区被迅速用完,绝大多数时候都会造成资源的严重浪费甚至是完全无法实现分配;开销大,回收后可能要重新排序。
优点:尽可能地利用存储器中大的空闲区,减少了难以利用的小碎片。
【数据结构设计】
(1)数据结构设计
为了实现存储资源的分配和回收,操作系统需要记录内存资源使用情况,即哪些区域尚未分配,哪些区域已经分配以及分配给哪些进程等。为此一般需要两个表,一个为分配表, 另外一个为空闲区域表。前者记录已经分配的区域, 后者记录着所有当前未被进程占用的空闲区域,如图1所示。
空闲区域首址 |
空闲区域长度 |
… |
… |
addr |
size |
… |
… |
图1 空闲区域表 |
显然, 没有记录于表中的区域即为已被进程所占用的非空闲区域,在实际的操作系统中,这些区域登记在进程的PCB中。而PCB中除了关于内存资源的信息外,还有其它大量信息。
由于本实验是对存储管理算法的模拟,所以用一个线程来代表一个进程,用线程驻留区域表来描述线程占用的内存空间,如图2所示。
线程名称 |
驻留区始址 |
驻留区大小 |
a |
0 |
10 |
b |
20 |
20 |
…… |
…… |
…… |
图2 线程驻留区表 |
同时,需要一张表来记录各个线程对内存的请求信息,如图3所示。
线程名称 |
请求大小(KB) |
预计驻留时间( 秒) |
thread_1 |
20 |
4 |
thread_2 |
10 |
5 |
…… |
…… |
…… |
图3 内存申请表 |
(2)设计并分析测试数据
假设初始内存布局如图4,图中的起始地址以及大小都以KB来衡量。
由图4可见,初始时共有五个线程驻留在内存,它们是a,b,c,d,e,线程驻留区表如图5;还有五个空闲区,空闲区域表如图6。
假设现在有三个线程提出内存申请,申请情况见图7。经过分析我们得到在每种分配算法下这三个线程所申请到的内存情况。图8是最先适应算法分配情况,图9是最佳适应算法分配情况,图10是最坏适应算法分配情况。
【算法设计】
宏定义:
#define Free 0 //空闲状态
#define Busy 1 //已用状态
#define OK 1 //完成
#define ERROR 0 //出错
#define MAX_length 640 //定义最大主存信息640KB
六大函数:
①status Alloc(int):内存分配函数。对于选择的首次适应算法或者是最佳适应算法判断分配完成状态,说明是否实现分配或者是分配错误。
②status free(int):内存回收函数。主要涉及合并内存的三种情况:
该空闲块与前面的空闲块相连的主存回收,表示为:
if (p->prior != block_first && p->prior->data.state == Free)
{
p->prior->data.size += p->data.size;//空间扩充,合并为一个
p->prior->next = p->next;//去掉原来被合并的p
p->next->prior = p->prior;
p = p->prior;
}
该空闲块与后面的空闲块相连,表示为:
if (p->next != block_last && p->next->data.state == Free) {
p->data.size += p->next->data.size;//空间扩充,合并为一个 p->next->next->prior = p;
p->next = p->next->next;
}
该空闲块与最后的空闲块相连,表示为:
if (p->next == block_last && p->next->data.state == Free) {
p->data.size += p->next->data.size;
p->next = NULL;
}
③status First_fit(int):首次适应算法,只需要将地址由小到大排列好,从头指针开始遍历,逐个检验,找到第一个空间>=所申请的空间时,给予分配。 temp->prior = p->prior;
temp->next = p;
temp->data.address = p->data.address;
p->prior->next = temp;
p->prior = temp;
p->data.address = temp->data.address + temp->data.size; p->data.size -= request;
④status Best_fit(int):对由小到大的空闲区排列的空闲区,与所申请的内存大小相比,取两者差最小的给予分配,插入。初始化最小空间和最佳位置,用ch来记录最小位置。
⑤void show():查看分配。
⑥status Initblock():开创带头结点的内存空间链表。
【程序代码】
#include<iostream>
#include<stdlib.h>
using namespace std;
#define Free 0 //空闲状态
#define Busy 1 //已用状态
#define OK 1 //完成
#define ERROR 0 //出错
#define MAX_length 640 //定义最大主存信息640KB
typedef int Status;
int flag;//标志位 0为空闲区 1为已分配的工作区
typedef struct FreAarea//定义一个空闲区说明表结构
{
long size; //分区大小
long address; //分区地址
int state; //状态
}ElemType;
typedef struct DuLNode// 线性表的双向链表存储结构
{
ElemType data;
struct DuLNode *prior; //前趋指针
struct DuLNode *next; //后继指针
}
DuLNode, *DuLinkList;
DuLinkList block_first; //头结点
DuLinkList block_last; //尾结点
Status Alloc(int);//内存分配
Status free(int); //内存回收
Status First_fit(int);//首次适应算法
Status Best_fit(int); //最佳适应算法
Status Worst_fit(int); //最差适应算法
void show();//查看分配
Status Initblock();//开创空间表
Status Initblock()//开创带头结点的内存空间链表
{
block_first = (DuLinkList)malloc(sizeof(DuLNode));
block_last = (DuLinkList)malloc(sizeof(DuLNode));
block_first->prior = NULL;
block_first->next = block_last;
block_last->prior = block_first;
block_last->next = NULL;
block_last->data.address = 0;
block_last->data.size = MAX_length;
block_last->data.state = Free;
return OK;
}
Status Alloc(int ch)//分配主存
{
int request = 0;
cout << "请输入需要分配的主存大小(单位:KB):"<<endl;
cin >> request;
if (request<0 || request == 0)
{
cout << "分配大小不合适,请重试!" << endl;
return ERROR;
}
if (ch == 2) //选择最佳适应算法
{
if (Best_fit(request) == OK) cout << "分配成功!" << endl;
else cout << "内存不足,分配失败!" << endl;
return OK;
}
if (ch == 3) //选择最差适应算法
{
if (Worst_fit(request) == OK) cout << "分配成功!" << endl;
else cout << "内存不足,分配失败!" << endl;
return OK;
}
else //默认首次适应算法
{
if (First_fit(request) == OK) cout << "分配成功!" << endl;
else cout << "内存不足,分配失败!" << endl;
return OK;
}
}
Status First_fit(int request)//首次适应算法
{
//为申请作业开辟新空间且初始化
DuLinkList temp = (DuLinkList)malloc(sizeof(DuLNode));
temp->data.size = request;
temp->data.state = Busy;
DuLNode *p = block_first->next;
while (p)
{
if (p->data.state == Free && p->data.size == request)
{//有大小恰好合适的空闲块
p->data.state = Busy;
return OK;
break;
}
if (p->data.state == Free && p->data.size>request)
{//有空闲块能满足需求且有剩余
temp->prior = p->prior;
temp->next = p;
temp->data.address = p->data.address;
p->prior->next = temp;
p->prior = temp;
p->data.address = temp->data.address + temp->data.size;
p->data.size -= request;
return OK;
break;
}
p = p->next;
}
return ERROR;
}
Status Best_fit(int request)//最佳适应算法
{
int ch; //记录最小剩余空间
DuLinkList temp = (DuLinkList)malloc(sizeof(DuLNode));
temp->data.size = request;
temp->data.state = Busy;
DuLNode *p = block_first->next;
DuLNode *q = NULL; //记录最佳插入位置
while (p) //初始化最小空间和最佳位置
{
if (p->data.state == Free && (p->data.size >= request))
{
if (q == NULL)
{
q = p;
ch = p->data.size - request;
}
else if (q->data.size > p->data.size)
{
q = p;
ch = p->data.size - request;
}
}
p = p->next;
}
if (q == NULL) return ERROR;//没有找到空闲块
else if (q->data.size == request)
{
q->data.state = Busy;
return OK;
}
else
{
temp->prior = q->prior;
temp->next = q;
temp->data.address = q->data.address;
q->prior->next = temp;
q->prior = temp;
q->data.address += request;
q->data.size = ch;
return OK;
}
return OK;
}
Status Worst_fit(int request)//最差适应算法
{
int ch; //记录最大剩余空间
DuLinkList temp = (DuLinkList)malloc(sizeof(DuLNode));
temp->data.size = request;
temp->data.state = Busy;
DuLNode *p = block_first->next;
DuLNode *q = NULL; //记录最佳插入位置
while (p) //初始化最大空间和最佳位置
{
if (p->data.state == Free && (p->data.size >= request))
{
if (q == NULL)
{
q = p;
ch = p->data.size - request;
}
else if (q->data.size < p->data.size)
{
q = p;
ch = p->data.size - request;
}
}
p = p->next;
}
if (q == NULL) return ERROR;//没有找到空闲块
else if (q->data.size == request)
{
q->data.state = Busy;
return OK;
}
else
{
temp->prior = q->prior;
temp->next = q;
temp->data.address = q->data.address;
q->prior->next = temp;
q->prior = temp;
q->data.address += request;
q->data.size = ch;
return OK;
}
return OK;
}
Status free(int flag)//主存回收
{
DuLNode *p = block_first;
for (int i = 0; i <= flag; i++)
if (p != NULL)
p = p->next;
else
return ERROR;
p->data.state = Free;
if (p->prior != block_first && p->prior->data.state == Free)//与前面的空闲块相连
{
p->prior->data.size += p->data.size;//空间扩充,合并为一个
p->prior->next = p->next;//去掉原来被合并的p
p->next->prior = p->prior;
p = p->prior;
}
if (p->next != block_last && p->next->data.state == Free)//与后面的空闲块相连
{
p->data.size += p->next->data.size;//空间扩充,合并为一个
p->next->next->prior = p;
p->next = p->next->next;
}
if (p->next == block_last && p->next->data.state == Free)//与最后的空闲块相连
{
p->data.size += p->next->data.size;
p->next = NULL;
}
return OK;
}
void show()//显示主存分配情况
{
int flag = 0;
cout << "\n主存分配情况:\n";
cout << "++++++++++++++++++++++++++++++++++++++++++++++\n\n";
DuLNode *p = block_first->next;
cout << "分区号\t起始地址\t分区大小\t状态\n\n";
while (p)
{
cout << " " << flag++ << "\t";
cout << " " << p->data.address << "\t\t";
cout << " " << p->data.size << "KB\t\t";
if (p->data.state == Free) cout << "空闲\n\n";
else cout << "已分配\n\n";
p = p->next;
}
cout << "++++++++++++++++++++++++++++++++++++++++++++++\n\n";
}
int main() //主函数
{
int ch;//算法选择标记
cout << "请输入所使用的内存分配算法:\n";
cout << "(1)首次适应算法\n(2)最佳适应算法\n(3)最坏适应算法\n";
cin >> ch;
while (ch<1 || ch>3)
{
cout << "输入错误,请重新输入所使用的内存分配算法:\n";
cin >> ch;
}
Initblock(); //开创空间表
int choice; //操作选择标记
while (1)
{
show();
cout << "请输入您的操作:";
cout << "\n1: 分配内存\n2: 回收内存\n0: 退出\n";
cin >> choice;
if (choice == 1) Alloc(ch); // 分配内存
else if (choice == 2) // 内存回收
{
int flag;
cout << "请输入您要释放的分区号:"<<endl;
cin >> flag;
free(flag);
}
else if (choice == 0) break; //退出
else //输入操作有误
{
cout << "输入有误,请重试!" << endl;
continue;
}
}
}
【实验结果】
假设初始状态下,可用的内存空间为640KB,并有下列的请求序列:
•作业1申请130KB •作业2申请60KB •作业3申请100KB •作业2释放60KB •作业4申请200KB •作业3释放100KB•作业1释放130KB •作业5申请140KB •作业6申请60KB •作业7申请50KB •作业6释放60KB。
首次适应:
最佳适应:
最坏适应:
【实验心得】
我在编写主存空间的分配和回收的过程中总结,从解决实际问题的角度,我们可以这样来看:首先要了解这个问题的基本要求,即输入、输出、完成从输入到输出的要求是什么;其次,从问题的要害入手,从前到后解决问题的每个方面,即从输入开始入手,着重考虑如何从输入导出输出。在这个过程中,可确定所需的变量、数组、函数,然后确定处理的过程,即算法。可得出最后的结论,进而完成程序的编写。经过这次实验,我对主存空间的分配和回收有了深一步的了解,同时也初步了解了内存空间的工作原理。总的来说这个实验既具有挑战性又极具趣味性。
以下是老师给的代码:
【程序结构】
程序包含两个文件,一个是头文件variable_partition.h,另一个是源程序文件variable_partition.cpp。在头文件中定义了宏、数据结构、全局变量、函数声明,源程序中含有各个函数的实现。
在头文件中,结构体FREEAREA、REQUIRE_MEMORY、THREAD_RESIDENCE_MEMORY分别对应于图1、图2、图3中的一行,不同之处是为了构成链表在三个结构体中都有前向指针。数组init_free_area_table对应于图6,数组init_thread_require_memory_table对应于图5,数组init_thread_residence_memory_table对应于图7,为了实现动态分配与释放,用链表重新组织空闲区域表、线程驻留区表和内存申请表,全局变量p_free_area_list是空闲区链首,p_thread_require_memory_queue是内存申请队列的队首,p_thread_residence_memory_list是线程驻留区链首,tail_thread_residence_memory_list是线程驻留区链尾,由于线程驻留区链表被内存分配函数和内存释放函数共享,故用临界区变量CS_THREAD_MEMORY_LIST来保护,同理,屏幕是所有线程共享的,所以用临界区变量CS_SCREEN来保护,空闲区链表被内存分配函数和内存释放函数共享,故用临界区变量CS_FREEAREA_LIST来保护。h_thread是线程句柄数组,用来存放各个线程的句柄。
程序共包含25个函数,按照作用可以将它们分成五组。
第一组是主函数main(),其作用是显示主菜单并根据用户的选择执行相应功能;
第二组包括函数print_space()和函数display_thread_residence_memory(),前者用来显示若干个空格,后者用来显示线程驻留区表;
第三组共十个函数,用来实现最先适应分配法,它们的名称及功能如图11。
第四组共六个函数,用来实现最佳适应分配法,它们的名称及功能如图12。
第五组共六个函数,用来实现最坏适应分配法,它们的名称及功能如图13。
【在Windows下运行的程序代码】
头文件 variable_partition.h 的清单
#include <windows.h>
#include <conio.h>
#include <stdlib.h>
#include <stdio.h>
#include <io.h>
#include <string.h>
#define MAX_THREAD 3
#define BF_initialize_require_memory_list FF_initialize_require_memory_list
#define WF_initialize_require_memory_list FF_initialize_require_memory_list
#define BF_initialize_thread_residence_memory_list FF_initialize_thread_residence_memory_list
#define WF_initialize_thread_residence_memory_list FF_initialize_thread_residence_memory_list
#define WF_delete_freearea_list FF_delete_freearea_list
#define BF_delete_freearea_list FF_delete_freearea_list
#define WF_delete_require_memory_list FF_delete_require_memory_list
#define BF_delete_require_memory_list FF_delete_require_memory_list
#define WF_delete_thread_residence_memory_list FF_delete_thread_residence_memory_list
#define BF_delete_thread_residence_memory_list FF_delete_thread_residence_memory_list
typedef struct freearea{ //表示空闲区域的数据结构
struct freearea *next; //指向下一个结点的指针
int start_address; //空闲区起始地址
int size; //空闲区大小
}FREEAREA;
typedef struct require_memory{ //记录线程申请内存的数据结构
struct require_memory *next; //指向下一个结点的指针
char thread_name[10]; //线程名
int size; //申请内存大小(以KB为单位)
int duration; //在内存的驻留时间(以秒为单位)
}REQUIRE_MEMORY;
typedef struct thread_residence_memory{ //描述线程驻留区的数据结构
struct thread_residence_memory *next; //指向下一个结点的指针
char thread_name[10]; //线程名
int start_address; //驻留区起始地址
int size; //驻留区大小
}THREAD_RESIDENCE_MEMORY;
FREEAREA init_free_area_table[5]={ //测试数据:初始空闲区表
{NULL,10,10},
{NULL,40,30},
{NULL,80,5},
{NULL,145,15},
{NULL,180,20}
};
REQUIRE_MEMORY init_thread_require_memory_table[3]={ //测试数据:初始内存申请表
{NULL,"thread_1",20,4},
{NULL,"thread_2",10,5},
{NULL,"thread_3",5,6}
};
//测试数据:初始线程驻留区表
THREAD_RESIDENCE_MEMORY init_thread_residence_memory_table[5]={
{NULL,"a",0,10},
{NULL,"b",20,20},
{NULL,"c",70,10},
{NULL,"d",85,60},
{NULL,"e",160,20}
};
FREEAREA *p_free_area_list=NULL; //空闲区链首
REQUIRE_MEMORY *p_thread_require_memory_queue=NULL; //内存申请队列队首
THREAD_RESIDENCE_MEMORY *p_thread_residence_memory_list=NULL; //线程驻留区链首
THREAD_RESIDENCE_MEMORY *tail_thread_residence_memory_list=NULL; //线程驻留区链尾
CRITICAL_SECTION CS_THREAD_MEMORY_LIST; //保护线程驻留区链表的临界区
CRITICAL_SECTION CS_SCREEN; //保护屏幕的临界区
CRITICAL_SECTION CS_FREEAREA_LIST; //保护空闲区链表的临界区
HANDLE h_thread[MAX_THREAD]; //线程句柄数组
void print_space(int num); //输出若干个空格
void display_thread_residence_memory_list(); //显示线程驻留区表
//最先适应分配法的函数
FREEAREA *FF_initialize_freearea_list(FREEAREA *init_table,int num); //初始化空闲区链表
void FF_delete_freearea_list(); //删除空闲区链表
REQUIRE_MEMORY *FF_initialize_require_memory_list(REQUIRE_MEMORY *init_table,int num);
//初始化内存申请链表
void FF_delete_require_memory_list(); //删除内存申请链表
THREAD_RESIDENCE_MEMORY *FF_initialize_thread_residence_memory_list
(THREAD_RESIDENCE_MEMORY *init_table,int num); //初始化线程驻留区链表
void FF_delete_thread_residence_memory_list(); //删除线程驻留区链表
void FF_thread(void *data); //线程函数
int FF_require_memory(int size); //内存申请函数
void FF_release_memory(int start_address,int size); //内存释放函数
void FF(); //最先适应分配算法的初始化函数
//最佳适应分配算法的函数
void BF_thread(void *data); //线程函数
int BF_require_memory(int size); //内存申请函数
void BF_release_memory(int start_address,int size); //内存释放函数
void BF_insert_freearea(FREEAREA *free_node); //空闲区结点插入函数
void BF(); //初始化程序
void BF_initialize_freearea_list(FREEAREA *init_table,int num); //初始化空闲区链表
//最坏适应分配算法的函数
void WF_thread(void *data); //线程函数
void WF_insert_freearea(FREEAREA *free_node); //空闲区结点插入函数
void WF_initialize_freearea_list(FREEAREA *init_table,int num); //初始化空闲区链表
int WF_require_memory(int size); //内存申请函数
void WF_release_memory(int start_address,int size); //内存释放函数
void WF(); //初始化程序
源程序文件 variable_partition.cpp 的清单
#include "variable_partition.h"
int main(int argc,char *argv[]){
char select;
while(1){
printf("|-----------------------------------|\n");
printf("| 1:first fit allocation |\n");
printf("| 2:best fit allocation |\n");
printf("| 3:worst fit allocation |\n");
printf("| 4:exit |\n");
printf("|-----------------------------------|\n");
printf("select a function(1~4):");
do{
select=(char)getch();
}while(select!='1'&&select!='2'&&select!='3'&&select!='4');
system("cls");
switch(select){
case '1':
FF();
break;
case '2':
BF();
break;
case '3':
WF();
break;
case '4':
return 0;
}
printf("\nPress any key to return to main menu.");
getch();
system("cls");
}
return 0;
}
void print_space(int num){ //显示若干个空格
int i;
for(i=0;i<num;i++){
printf(" ");
}
}
void display_thread_residence_memory_list(){ //显示驻留线程链表
THREAD_RESIDENCE_MEMORY *p;
char buffer[20];
p=p_thread_residence_memory_list;
printf("|-------------------|--------------------|------------------|\n");
printf("| thread_name | start_address(kB) | size(KB) |\n");
printf("|-------------------|--------------------|------------------|\n");
while(p!=NULL){
printf("| %s",p->thread_name);
print_space(18-strlen(p->thread_name));
printf("| %d",p->start_address);
itoa( p->start_address, buffer, 10 );
print_space(19-strlen(buffer));
printf("| %d",p->size);
itoa(p->size, buffer, 10 );
print_space(17-strlen(buffer));
printf("|\n");
p=p->next;
};
printf("|-------------------|--------------------|------------------|\n\n");
}
//最先适应分配法:初始化空闲区链表
FREEAREA *FF_initialize_freearea_list(FREEAREA *init_table,int num){
FREEAREA *temp;
FREEAREA *head=NULL;
FREEAREA *tail=NULL;
int i;
for(i=0;i<num;i++){
temp=(FREEAREA *)malloc(sizeof(FREEAREA));
temp->start_address=init_table[i].start_address;
temp->size=init_table[i].size;
temp->next=NULL;
if(head==NULL)
head=tail=temp;
else{
tail->next=temp;
tail=tail->next;
}
};
return head;
}
//最先适应分配法:删除空闲区链表
void FF_delete_freearea_list(){
FREEAREA *temp;
temp=p_free_area_list;
while(temp!=NULL){
temp=p_free_area_list->next;
free(p_free_area_list);
p_free_area_list=temp;
}
p_free_area_list=NULL;
}
//最先适应分配法:初始化内存申请链表
REQUIRE_MEMORY *FF_initialize_require_memory_list(REQUIRE_MEMORY *init_table,int num){
REQUIRE_MEMORY *temp;
REQUIRE_MEMORY *head=NULL;
REQUIRE_MEMORY *tail=NULL;
int i;
for(i=0;i<num;i++){
temp=(REQUIRE_MEMORY *)malloc(sizeof(REQUIRE_MEMORY));
strcpy(temp->thread_name,init_table[i].thread_name);
temp->size=init_table[i].size;
temp->duration=init_table[i].duration;
temp->next=NULL;
if(head==NULL)
head=tail=temp;
else{
tail->next=temp;
tail=tail->next;
}
};
return head;
}
//最先适应分配法:删除内存申请链表
void FF_delete_require_memory_list(){
REQUIRE_MEMORY *temp;
temp=p_thread_require_memory_queue;
while(temp!=NULL){
temp=p_thread_require_memory_queue->next;
free(p_thread_require_memory_queue);
p_thread_require_memory_queue=temp;
}
p_thread_require_memory_queue=NULL;
}
//最先适应分配法:初始化线程驻留区链表
THREAD_RESIDENCE_MEMORY *FF_initialize_thread_residence_memory_list(THREAD_RESIDENCE_MEMORY *init_table,int num){
THREAD_RESIDENCE_MEMORY *temp;
THREAD_RESIDENCE_MEMORY *head=NULL;
THREAD_RESIDENCE_MEMORY *tail=NULL;
int i;
for(i=0;i<num;i++){
temp=(THREAD_RESIDENCE_MEMORY *)malloc(sizeof(THREAD_RESIDENCE_MEMORY));
strcpy(temp->thread_name,init_table[i].thread_name);
temp->start_address=init_table[i].start_address;
temp->size=init_table[i].size;
temp->next=NULL;
if(head==NULL)
head=tail=temp;
else{
tail->next=temp;
tail=tail->next;
}
};
tail_thread_residence_memory_list=tail;
return head;
}
//最先适应分配法:删除线程驻留区链表
void FF_delete_thread_residence_memory_list(){
THREAD_RESIDENCE_MEMORY *temp=p_thread_residence_memory_list;
temp=p_thread_residence_memory_list;
while(temp!=NULL){
temp=p_thread_residence_memory_list->next;
free(p_thread_residence_memory_list);
p_thread_residence_memory_list=temp;
}
p_thread_residence_memory_list=NULL;
}
//线程:申请内存,驻留一段时间,释放内存
void FF_thread(void *data){
int start_address=-1;
THREAD_RESIDENCE_MEMORY *temp;
EnterCriticalSection(&CS_SCREEN);
printf("create thread:%s\n",((REQUIRE_MEMORY *)(data))->thread_name);
LeaveCriticalSection(&CS_SCREEN);
while(1){ //申请内存
start_address=FF_require_memory(((REQUIRE_MEMORY *)(data))->size);
if(start_address>=0)
break;
else
Sleep(1000);
}
temp=(THREAD_RESIDENCE_MEMORY *)malloc(sizeof(THREAD_RESIDENCE_MEMORY));
strcpy(temp->thread_name,((REQUIRE_MEMORY *)(data))->thread_name);
temp->start_address=start_address;
temp->size=((REQUIRE_MEMORY *)(data))->size;
temp->next=NULL;
EnterCriticalSection(&CS_THREAD_MEMORY_LIST);
//加入线程驻留区链表
tail_thread_residence_memory_list->next=temp;
tail_thread_residence_memory_list=tail_thread_residence_memory_list->next;
LeaveCriticalSection(&CS_THREAD_MEMORY_LIST);
//显示线程驻留区链表
EnterCriticalSection(&CS_SCREEN);
printf("after %s %s\n",((REQUIRE_MEMORY *)(data))->thread_name,"get memory:");
display_thread_residence_memory_list();
LeaveCriticalSection(&CS_SCREEN);
Sleep(((REQUIRE_MEMORY *)(data))->duration);
//释放内存
FF_release_memory(start_address,((REQUIRE_MEMORY *)(data))->size);
}
//最先适应分配法:内存申请函数
int FF_require_memory(int size){
int start_address=-1;
FREEAREA *p;
FREEAREA *p_next;
EnterCriticalSection(&CS_FREEAREA_LIST);
p=p_next=p_free_area_list;
while(p_next!=NULL){
if(size==p_next->size){ //刚好满足要求,删除空闲区结点
start_address=p_next->start_address;
if(p_next==p_free_area_list)
p_free_area_list=p_next->next;
else
p->next=p_next->next;
free(p_next);
break;
}
else
if(size<p_next->size){ //分割空闲区结点
start_address=p_next->start_address;
p_next->start_address+=size;
p_next->size-=size;
break;
}
else
{
p=p_next;
p_next=p_next->next;
}
}
LeaveCriticalSection(&CS_FREEAREA_LIST);
return start_address;
}
//最先适应分配法:内存释放函数
void FF_release_memory(int start_address,int size){
EnterCriticalSection(&CS_FREEAREA_LIST);
//请读者自己实现这段代码
LeaveCriticalSection(&CS_FREEAREA_LIST);
}
//最先适应分配算法的初始化程序
void FF(){
int i=0;
REQUIRE_MEMORY *p;
HANDLE h_thread[MAX_THREAD];
InitializeCriticalSection(&CS_THREAD_MEMORY_LIST);
InitializeCriticalSection(&CS_FREEAREA_LIST);
InitializeCriticalSection(&CS_SCREEN);
printf("最先适应分配算法\n");
p_free_area_list=FF_initialize_freearea_list(init_free_area_table,5);
p_thread_require_memory_queue=FF_initialize_require_memory_list(init_thread_require_memory_table,3);
p_thread_residence_memory_list=FF_initialize_thread_residence_memory_list(init_thread_residence_memory_table,5);
p=p_thread_require_memory_queue;
while(p!=NULL){
h_thread[i]=CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)(FF_thread),p,0,NULL);
i++;
p=p->next;
};
WaitForMultipleObjects(MAX_THREAD,h_thread,TRUE,-1); //等待所有线程结束
EnterCriticalSection(&CS_SCREEN);
printf("after all threads have finished:\n");
display_thread_residence_memory_list(); //显示驻留线程链表
LeaveCriticalSection(&CS_SCREEN);
//删除各种链表
FF_delete_freearea_list();
FF_delete_require_memory_list();
FF_delete_thread_residence_memory_list();
getch();
printf("\n");
}
//最佳适应分配算法的线程:申请内存,驻留一段时间,释放内存
void BF_thread(void *data){
int start_address=-1;
THREAD_RESIDENCE_MEMORY *temp;
EnterCriticalSection(&CS_SCREEN);
printf("create thread:%s\n",((REQUIRE_MEMORY *)(data))->thread_name);
LeaveCriticalSection(&CS_SCREEN);
//申请内存
while(1){
start_address=BF_require_memory(((REQUIRE_MEMORY *)(data))->size);
if(start_address>=0)
break;
else
Sleep(1000);
}
temp=(THREAD_RESIDENCE_MEMORY *)malloc(sizeof(THREAD_RESIDENCE_MEMORY));
strcpy(temp->thread_name,((REQUIRE_MEMORY *)(data))->thread_name);
temp->start_address=start_address;
temp->size=((REQUIRE_MEMORY *)(data))->size;
temp->next=NULL;
EnterCriticalSection(&CS_THREAD_MEMORY_LIST);
//加入线程内存驻留区链表
tail_thread_residence_memory_list->next=temp;
tail_thread_residence_memory_list=tail_thread_residence_memory_list->next;
LeaveCriticalSection(&CS_THREAD_MEMORY_LIST);
//显示线程内存驻留区链表
EnterCriticalSection(&CS_SCREEN);
printf("after %s %s\n",((REQUIRE_MEMORY *)(data))->thread_name,"get memory:");
display_thread_residence_memory_list();
LeaveCriticalSection(&CS_SCREEN);
Sleep(((REQUIRE_MEMORY *)(data))->duration);
//释放内存
BF_release_memory(start_address,((REQUIRE_MEMORY *)(data))->size);
}
//最佳适应分配算法的内存申请函数
int BF_require_memory(int size){
int start_address=-1;
FREEAREA *p;
FREEAREA *p_next;
EnterCriticalSection(&CS_FREEAREA_LIST);
p=p_next=p_free_area_list;
while(p_next!=NULL){
if(size==p_next->size){//刚好满足要求,删除空闲区结点
start_address=p_next->start_address;
if(p_next==p_free_area_list)
p_free_area_list=p_next->next;
else
p->next=p_next->next;
free(p_next);
break;
}
else
if(size<p_next->size){//分割空闲区结点
start_address=p_next->start_address;
p_next->start_address+=size;
p_next->size-=size;
p->next=p_next->next;
BF_insert_freearea(p_next);
break;
}
else
{
p=p_next;
p_next=p_next->next;
}
}
LeaveCriticalSection(&CS_FREEAREA_LIST);
return start_address;
}
//最佳适应分配算法的内存释放函数
void BF_release_memory(int start_address,int size){
//请读者自己实现这段代码
}
//最佳分配算法的空闲区结点插入函数
void BF_insert_freearea(FREEAREA *free_node){
FREEAREA *p;
FREEAREA *p_next;
if(p_free_area_list==NULL)
p_free_area_list=free_node;
else{
p_next=p=p_free_area_list;
while(p_next!=NULL&&p_next->size<free_node->size){
p=p_next;
p_next=p_next->next;
}
if(p_next==NULL) //应插入到尾部
p->next=free_node;
else
if(p==p_next){ //应插入到头部
free_node->next=p;
p_free_area_list=free_node;
}
else{ //应插入到p与p_next之间
free_node->next=p_next;
p->next=free_node;
}
}
}
//最佳适应分配法:初始化空闲区链表
void BF_initialize_freearea_list(FREEAREA *init_table,int num){
FREEAREA *temp;
int i;
for(i=0;i<num;i++){
temp=(FREEAREA *)malloc(sizeof(FREEAREA));
temp->start_address=init_table[i].start_address;
temp->size=init_table[i].size;
temp->next=NULL;
BF_insert_freearea(temp);
}
}
//最佳分配算法的初始化程序
void BF(){
int i=0;
REQUIRE_MEMORY *p;
HANDLE h_thread[MAX_THREAD];
InitializeCriticalSection(&CS_THREAD_MEMORY_LIST);
InitializeCriticalSection(&CS_FREEAREA_LIST);
InitializeCriticalSection(&CS_SCREEN);
printf("最佳适应分配算法\n");
BF_initialize_freearea_list(init_free_area_table,5);
p_thread_require_memory_queue=BF_initialize_require_memory_list(init_thread_require_memory_table,3);
p_thread_residence_memory_list=BF_initialize_thread_residence_memory_list(init_thread_residence_memory_table,5);
p=p_thread_require_memory_queue;
while(p!=NULL){
h_thread[i]=CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)(BF_thread),p,0,NULL);
i++;
p=p->next;
};
//等待所有线程结束
WaitForMultipleObjects(MAX_THREAD,h_thread,TRUE,-1);
//显示驻留线程链表
EnterCriticalSection(&CS_SCREEN);
printf("after all threads have finished:\n");
display_thread_residence_memory_list();
LeaveCriticalSection(&CS_SCREEN);
//删除各种链表
FF_delete_freearea_list();
FF_delete_require_memory_list();
FF_delete_thread_residence_memory_list();
getch();
printf("\n");
}
//最坏适应分配算法的线程:申请内存,驻留一段时间,释放内存
void WF_thread(void *data){
int start_address=-1;
THREAD_RESIDENCE_MEMORY *temp;
EnterCriticalSection(&CS_SCREEN);
printf("create thread:%s\n",((REQUIRE_MEMORY *)(data))->thread_name);
LeaveCriticalSection(&CS_SCREEN);
//申请内存
while(1){
start_address=WF_require_memory(((REQUIRE_MEMORY *)(data))->size);
if(start_address>=0)
break;
else
Sleep(1000);
}
temp=(THREAD_RESIDENCE_MEMORY *)malloc(sizeof(THREAD_RESIDENCE_MEMORY));
strcpy(temp->thread_name,((REQUIRE_MEMORY *)(data))->thread_name);
temp->start_address=start_address;
temp->size=((REQUIRE_MEMORY *)(data))->size;
temp->next=NULL;
EnterCriticalSection(&CS_THREAD_MEMORY_LIST);
//加入线程内存驻留区链表
tail_thread_residence_memory_list->next=temp;
tail_thread_residence_memory_list=tail_thread_residence_memory_list->next;
LeaveCriticalSection(&CS_THREAD_MEMORY_LIST);
//显示线程内存驻留区链表
EnterCriticalSection(&CS_SCREEN);
printf("after %s %s\n",((REQUIRE_MEMORY *)(data))->thread_name,"get memory:");
display_thread_residence_memory_list();
LeaveCriticalSection(&CS_SCREEN);
Sleep(((REQUIRE_MEMORY *)(data))->duration);
//释放内存
WF_release_memory(start_address,((REQUIRE_MEMORY *)(data))->size);
}
//最坏分配算法的空闲区结点插入函数
void WF_insert_freearea(FREEAREA *free_node){
FREEAREA *p;
FREEAREA *p_next;
if(p_free_area_list==NULL)
p_free_area_list=free_node;
else{
p=p_next=p_free_area_list;
while(p_next!=NULL&&free_node->size<p_next->size){
p=p_next;
p_next=p_next->next;
}
if(p_next==NULL) //应插入到尾部
p->next=free_node;
else
if(p==p_next){ //应插入到头部
free_node->next=p;
p_free_area_list=free_node;
}
else{ //应插入到p与p_next之间
free_node->next=p_next;
p->next=free_node;
}
}
}
//最坏适应分配法:初始化空闲区链表
void WF_initialize_freearea_list(FREEAREA *init_table,int num){
FREEAREA *temp;
int i;
for(i=0;i<num;i++){
temp=(FREEAREA *)malloc(sizeof(FREEAREA));
temp->start_address=init_table[i].start_address;
temp->size=init_table[i].size;
temp->next=NULL;
WF_insert_freearea(temp);
}
}
//最坏适应分配算法的内存申请函数
int WF_require_memory(int size){
int start_address=-1;
FREEAREA *p_next;
EnterCriticalSection(&CS_FREEAREA_LIST);
p_next=p_free_area_list;
if(size==p_free_area_list->size){//刚好满足要求,删除空闲区结点
start_address=p_next->start_address;
p_free_area_list=p_free_area_list->next;
free(p_next);
}
else
if(size<p_next->size){//分割空闲区结点
start_address=p_next->start_address;
p_next->start_address+=size;
p_next->size-=size;
p_free_area_list=p_free_area_list->next;
WF_insert_freearea(p_next);
}
LeaveCriticalSection(&CS_FREEAREA_LIST);
return start_address;
}
//最坏适应分配算法:内存释放函数
void WF_release_memory(int start_address,int size){
//请读者自己实现这段代码
}
//最坏适应分配算法的初始化程序
void WF(){
int i=0;
REQUIRE_MEMORY *p;
HANDLE h_thread[MAX_THREAD];
InitializeCriticalSection(&CS_THREAD_MEMORY_LIST);
InitializeCriticalSection(&CS_FREEAREA_LIST);
InitializeCriticalSection(&CS_SCREEN);
printf("最坏适应分配算法\n");
WF_initialize_freearea_list(init_free_area_table,5);
p_thread_require_memory_queue=WF_initialize_require_memory_list(init_thread_require_memory_table,3);
p_thread_residence_memory_list=WF_initialize_thread_residence_memory_list(init_thread_residence_memory_table,5);
p=p_thread_require_memory_queue;
while(p!=NULL){
h_thread[i]=CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)(WF_thread),p,0,NULL);
i++;
p=p->next;
};
//等待所有线程结束
WaitForMultipleObjects(MAX_THREAD,h_thread,TRUE,-1);
//显示驻留线程链表
EnterCriticalSection(&CS_SCREEN);
printf("after all threads have finished:\n");
display_thread_residence_memory_list();
LeaveCriticalSection(&CS_SCREEN);
//删除各种链表
FF_delete_freearea_list();
FF_delete_require_memory_list();
FF_delete_thread_residence_memory_list();
getch();
printf("\n");
}
【在Linux下运行的代码】
编译命令:gcc variable_partition .cpp –o variable_partition.o –lcurses –lpthread
头文件variable_partition.h
#include <unistd.h>
#include <curses.h>
#include <stdlib.h>
#include <pthread.h>
#include <time.h>
#include <string.h>
#include <semaphore.h>
#define MAX_THREAD 3
#define BF_initialize_require_memory_list FF_initialize_require_memory_list
#define WF_initialize_require_memory_list FF_initialize_require_memory_list
#define BF_initialize_thread_residence_memory_list
FF_initialize_thread_residence_memory_list
#define WF_initialize_thread_residence_memory_list
FF_initialize_thread_residence_memory_list
#define WF_delete_freearea_list FF_delete_freearea_list
#define BF_delete_freearea_list FF_delete_freearea_list
#define WF_delete_require_memory_list FF_delete_require_memory_list
#define BF_delete_require_memory_list FF_delete_require_memory_list
#define WF_delete_thread_residence_memory_list
FF_delete_thread_residence_memory_list
#define BF_delete_thread_residence_memory_list
FF_delete_thread_residence_memory_list
typedef struct freearea{
struct freearea *next;
int start_address;
int size;
}FREEAREA;
typedef struct require_memory{
struct require_memory *next;
char thread_name[10];
int size;
int duration;
}REQUIRE_MEMORY;
typedef struct thread_residence_memory{
struct thread_residence_memory *next;
char thread_name[10];
int start_address;
int size;
}THREAD_RESIDENCE_MEMORY;
FREEAREA init_free_area_table[5]={
{NULL,10,10},
{NULL,40,30},
{NULL,80,5},
{NULL,145,15},
{NULL,180,20}
};
REQUIRE_MEMORY init_thread_require_memory_table[3]={
{NULL,"thread_1",20,4},
{NULL,"thread_2",10,5},
{NULL,"thread_3",5,6}
};
THREAD_RESIDENCE_MEMORY init_thread_residence_memory_table[5]={
{NULL,"a",0,10},
{NULL,"b",20,20},
{NULL,"c",70,10},
{NULL,"d",85,60},
{NULL,"e",160,20}
};
FREEAREA *p_free_area_list=NULL;
REQUIRE_MEMORY *p_thread_require_memory_queue=NULL;
THREAD_RESIDENCE_MEMORY *p_thread_residence_memory_list=NULL;
THREAD_RESIDENCE_MEMORY *tail_thread_residence_memory_list=NULL;
pthread_mutex_t CS_THREAD_MEMORY_LIST;
pthread_mutex_t CS_SCREEN;
pthread_mutex_t CS_FREEAREA_LIST;
pthread_t h_thread[MAX_THREAD];
sem_t thread_end[MAX_THREAD];
void display_thread_residence_memory_list();
FREEAREA *FF_initialize_freearea_list(FREEAREA *init_table,int num);
void FF_delete_freearea_list();
REQUIRE_MEMORY *FF_initialize_require_memory_list(REQUIRE_MEMORY *init_table,
int num);
void FF_delete_require_memory_list();
THREAD_RESIDENCE_MEMORY *FF_initialize_thread_residence_memory_list
(
THREAD_RESIDENCE_MEMORY *init_table,
int num
);
void FF_delete_thread_residence_memory_list();
void* FF_thread(void *data);
int FF_require_memory(int size);
void FF_release_memory(int start_address,int size);
void FF();
void* BF_thread(void *data);
int BF_require_memory(int size);
void BF_release_memory(int start_address,int size);
void BF_insert_freearea(FREEAREA *free_node);
void BF();
void BF_initialize_freearea_list(FREEAREA *init_table,int num);
void* WF_thread(void *data);
void WF_insert_freearea(FREEAREA *free_node);
void WF_initialize_freearea_list(FREEAREA *init_table,int num);
int WF_require_memory(int size);
void WF_release_memory(int start_address,int size);
void WF();
源文件variable_partition.cpp
#include "variable_partition.h"
int main(int argc,char *argv[]){
char select;
bool end=false;
initscr();
while(!end){
clear();
refresh();
printw("|-----------------------------------|\n");
printw("| 1:first fit allocation |\n");
printw("| 2:best fit allocation |\n");
printw("| 3:worst fit allocation |\n");
printw("| 4:exit |\n");
printw("|-----------------------------------|\n");
printw("select a function(1~4):");
do{
select=(char)getch();
}while(select!='1'&&select!='2'&&select!='3'&&select!='4');
clear();
refresh();
switch(select){
case '1':
FF();
break;
case '2':
BF();
break;
case '3':
WF();
break;
case '4':
end=true;
}
printw("\nPress any key to return to main menu.");
refresh();
getch();
}
endwin();
return 0;
}
void display_thread_residence_memory_list(){
THREAD_RESIDENCE_MEMORY *p;
p=p_thread_residence_memory_list;
int i=13;
move(10,0);
printw("|-------------------|--------------------|------------------|\n");
printw("| thread_name | start_address(kB) | size(KB) |\n");
printw("|-------------------|--------------------|------------------|\n");
while(p!=NULL){
move(i,0);
printw("| %s",p->thread_name);
move(i,20);
printw("| %d",p->start_address);
move(i,41);
printw("| %d",p->size);
move(i,60);
printw("|\n");
p=p->next;
i++;
};
move(i,0);
printw("|-------------------|--------------------|------------------|\n\n");
refresh();
}
FREEAREA *FF_initialize_freearea_list(FREEAREA *init_table,int num){
FREEAREA *temp;
FREEAREA *head=NULL;
FREEAREA *tail=NULL;
int i;
for(i=0;i<num;i++){
temp=(FREEAREA *)malloc(sizeof(FREEAREA));
temp->start_address=init_table[i].start_address;
temp->size=init_table[i].size;
temp->next=NULL;
if(head==NULL)
head=tail=temp;
else{
tail->next=temp;
tail=tail->next;
}
};
return head;
}
void FF_delete_freearea_list(){
FREEAREA *temp;
temp=p_free_area_list;
while(temp!=NULL){
temp=p_free_area_list->next;
free(p_free_area_list);
p_free_area_list=temp;
}
p_free_area_list=NULL;
}
REQUIRE_MEMORY *
FF_initialize_require_memory_list(REQUIRE_MEMORY *init_table,int num)
{
REQUIRE_MEMORY *temp;
REQUIRE_MEMORY *head=NULL;
REQUIRE_MEMORY *tail=NULL;
int i;
for(i=0;i<num;i++){
temp=(REQUIRE_MEMORY *)malloc(sizeof(REQUIRE_MEMORY));
strcpy(temp->thread_name,init_table[i].thread_name);
temp->size=init_table[i].size;
temp->duration=init_table[i].duration;
temp->next=NULL;
if(head==NULL)
head=tail=temp;
else{
tail->next=temp;
tail=tail->next;
}
};
return head;
}
void FF_delete_require_memory_list(){
REQUIRE_MEMORY *temp;
temp=p_thread_require_memory_queue;
while(temp!=NULL){
temp=p_thread_require_memory_queue->next;
free(p_thread_require_memory_queue);
p_thread_require_memory_queue=temp;
}
p_thread_require_memory_queue=NULL;
}
THREAD_RESIDENCE_MEMORY
*FF_initialize_thread_residence_memory_list
(THREAD_RESIDENCE_MEMORY *init_table,int num)
{
THREAD_RESIDENCE_MEMORY *temp;
THREAD_RESIDENCE_MEMORY *head=NULL;
THREAD_RESIDENCE_MEMORY *tail=NULL;
int i;
for(i=0;i<num;i++){
temp=(THREAD_RESIDENCE_MEMORY *)malloc(sizeof(THREAD_RESIDENCE_MEMORY));
strcpy(temp->thread_name,init_table[i].thread_name);
temp->start_address=init_table[i].start_address;
temp->size=init_table[i].size;
temp->next=NULL;
if(head==NULL)
head=tail=temp;
else{
tail->next=temp;
tail=tail->next;
}
};
tail_thread_residence_memory_list=tail;
return head;
}
void FF_delete_thread_residence_memory_list(){
THREAD_RESIDENCE_MEMORY *temp=p_thread_residence_memory_list;
temp=p_thread_residence_memory_list;
while(temp!=NULL){
temp=p_thread_residence_memory_list->next;
free(p_thread_residence_memory_list);
p_thread_residence_memory_list=temp;
}
p_thread_residence_memory_list=NULL;
}
void* FF_thread(void *data){
int start_address=-1;
int i=(((REQUIRE_MEMORY *)(data))->thread_name)[7]-49;
THREAD_RESIDENCE_MEMORY *temp;
pthread_mutex_lock(&CS_SCREEN);
printw("create thread:%s\n",((REQUIRE_MEMORY *)(data))->thread_name);
refresh();
pthread_mutex_unlock(&CS_SCREEN);
while(1){
start_address=FF_require_memory(((REQUIRE_MEMORY *)(data))->size);
if(start_address>=0)
break;
else
sleep(1);
}
temp=(THREAD_RESIDENCE_MEMORY *)malloc(sizeof(THREAD_RESIDENCE_MEMORY));
strcpy(temp->thread_name,((REQUIRE_MEMORY *)(data))->thread_name);
temp->start_address=start_address;
temp->size=((REQUIRE_MEMORY *)(data))->size;
temp->next=NULL;
pthread_mutex_lock(&CS_THREAD_MEMORY_LIST);
tail_thread_residence_memory_list->next=temp;
tail_thread_residence_memory_list=tail_thread_residence_memory_list->next;
pthread_mutex_unlock(&CS_THREAD_MEMORY_LIST);
sleep(((REQUIRE_MEMORY *)(data))->duration);
FF_release_memory(start_address,((REQUIRE_MEMORY *)(data))->size);
sem_post(&thread_end[i]);
return 0;
}
int FF_require_memory(int size){
int start_address=-1;
FREEAREA *p;
FREEAREA *p_next;
pthread_mutex_lock(&CS_FREEAREA_LIST);
p=p_next=p_free_area_list;
while(p_next!=NULL){
if(size==p_next->size){
start_address=p_next->start_address;
if(p_next==p_free_area_list)
p_free_area_list=p_next->next;
else
p->next=p_next->next;
free(p_next);
break;
}
else
if(size<p_next->size){
start_address=p_next->start_address;
p_next->start_address+=size;
p_next->size-=size;
break;
}
else
{
p=p_next;
p_next=p_next->next;
}
}
pthread_mutex_unlock(&CS_FREEAREA_LIST);
return start_address;
}
void FF_release_memory(int start_address,int size){
pthread_mutex_lock(&CS_FREEAREA_LIST);
pthread_mutex_unlock(&CS_FREEAREA_LIST);
}
void FF(){
int i=0;
int j=0;
REQUIRE_MEMORY *p;
for(j=0;j<MAX_THREAD;j++){
sem_init(&thread_end[j],0,0);
}
pthread_mutex_init(&CS_THREAD_MEMORY_LIST,NULL);
pthread_mutex_init(&CS_FREEAREA_LIST,NULL);
pthread_mutex_init(&CS_SCREEN,NULL);
printw("First Fit\n");
refresh();
p_free_area_list=FF_initialize_freearea_list(init_free_area_table,5);
p_thread_require_memory_queue=FF_initialize_require_memory_list(init_thread_require_memory_table,3);
p_thread_residence_memory_list=FF_initialize_thread_residence_memory_list
(init_thread_residence_memory_table,5);
p=p_thread_require_memory_queue;
while(p!=NULL){
pthread_create(&h_thread[i],NULL,FF_thread,p);
i++;
p=p->next;
};
for(j=0;j<MAX_THREAD;j++){
sem_wait(&thread_end[j]);
}
pthread_mutex_lock(&CS_SCREEN);
printw("after all threads have finished:\n");
refresh();
display_thread_residence_memory_list();
pthread_mutex_unlock(&CS_SCREEN);
FF_delete_freearea_list();
FF_delete_require_memory_list();
FF_delete_thread_residence_memory_list();
for(j=0;j<MAX_THREAD;j++){
sem_destroy(&thread_end[j]);
}
getch();
printw("\n");
refresh();
}
void* BF_thread(void *data){
int start_address=-1;
int i=(((REQUIRE_MEMORY *)(data))->thread_name)[7]-49;
THREAD_RESIDENCE_MEMORY *temp;
pthread_mutex_lock(&CS_SCREEN);
printw("create thread:%s\n",((REQUIRE_MEMORY *)(data))->thread_name);
refresh();
pthread_mutex_unlock(&CS_SCREEN);
while(1){
start_address=BF_require_memory(((REQUIRE_MEMORY *)(data))->size);
if(start_address>=0)
break;
else
sleep(1);
}
temp=(THREAD_RESIDENCE_MEMORY *)malloc(sizeof(THREAD_RESIDENCE_MEMORY));
strcpy(temp->thread_name,((REQUIRE_MEMORY *)(data))->thread_name);
temp->start_address=start_address;
temp->size=((REQUIRE_MEMORY *)(data))->size;
temp->next=NULL;
pthread_mutex_lock(&CS_THREAD_MEMORY_LIST);
tail_thread_residence_memory_list->next=temp;
tail_thread_residence_memory_list=tail_thread_residence_memory_list->next;
pthread_mutex_unlock(&CS_THREAD_MEMORY_LIST);
sleep(((REQUIRE_MEMORY *)(data))->duration);
BF_release_memory(start_address,((REQUIRE_MEMORY *)(data))->size);
sem_post(&thread_end[i]);
return 0;
}
int BF_require_memory(int size){
int start_address=-1;
FREEAREA *p;
FREEAREA *p_next;
pthread_mutex_lock(&CS_FREEAREA_LIST);
p=p_next=p_free_area_list;
while(p_next!=NULL){
if(size==p_next->size){
start_address=p_next->start_address;
if(p_next==p_free_area_list)
p_free_area_list=p_next->next;
else
p->next=p_next->next;
free(p_next);
break;
}
else
if(size<p_next->size){
start_address=p_next->start_address;
p_next->start_address+=size;
p_next->size-=size;
p->next=p_next->next;
BF_insert_freearea(p_next);
break;
}
else
{
p=p_next;
p_next=p_next->next;
}
}
pthread_mutex_unlock(&CS_FREEAREA_LIST);
return start_address;
}
void BF_release_memory(int start_address,int size){
}
void BF_insert_freearea(FREEAREA *free_node){
FREEAREA *p;
FREEAREA *p_next;
if(p_free_area_list==NULL)
p_free_area_list=free_node;
else{
p_next=p=p_free_area_list;
while(p_next!=NULL&&p_next->size<free_node->size){
p=p_next;
p_next=p_next->next;
}
if(p_next==NULL)
p->next=free_node;
else
if(p==p_next){
free_node->next=p;
p_free_area_list=free_node;
}
else{
free_node->next=p_next;
p->next=free_node;
}
}
}
void BF_initialize_freearea_list(FREEAREA *init_table,int num){
FREEAREA *temp;
int i;
for(i=0;i<num;i++){
temp=(FREEAREA *)malloc(sizeof(FREEAREA));
temp->start_address=init_table[i].start_address;
temp->size=init_table[i].size;
temp->next=NULL;
BF_insert_freearea(temp);
}
}
void BF(){
int i=0;
int j=0;
REQUIRE_MEMORY *p;
for(j=0;j<MAX_THREAD;j++){
sem_init(&thread_end[j],0,0);
}
pthread_mutex_init(&CS_THREAD_MEMORY_LIST,NULL);
pthread_mutex_init(&CS_FREEAREA_LIST,NULL);
pthread_mutex_init(&CS_SCREEN,NULL);
printw("Best Fit\n");
refresh();
BF_initialize_freearea_list(init_free_area_table,5);
p_thread_require_memory_queue=BF_initialize_require_memory_list(init_thread_require_memory_table,3);
p_thread_residence_memory_list=BF_initialize_thread_residence_memory_list
(init_thread_residence_memory_table,5);
p=p_thread_require_memory_queue;
while(p!=NULL){
pthread_create(&h_thread[i],NULL,BF_thread,p);
i++;
p=p->next;
};
for(j=0;j<MAX_THREAD;j++)
{sem_wait(&thread_end[j]);}
pthread_mutex_lock(&CS_SCREEN);
printw("after all threads have finished:\n");
refresh();
display_thread_residence_memory_list();
pthread_mutex_unlock(&CS_SCREEN);
FF_delete_freearea_list();
FF_delete_require_memory_list();
FF_delete_thread_residence_memory_list();
for(j=0;j<MAX_THREAD;j++){
sem_destroy(&thread_end[j]);
}
getch();
printw("\n");
refresh();
}
void* WF_thread(void *data){
int start_address=-1;
int i=(((REQUIRE_MEMORY *)(data))->thread_name)[7]-49;
THREAD_RESIDENCE_MEMORY *temp;
pthread_mutex_lock(&CS_SCREEN);
printw("create thread:%s\n",((REQUIRE_MEMORY *)(data))->thread_name);
refresh();
pthread_mutex_unlock(&CS_SCREEN);
while(1){
start_address=WF_require_memory(((REQUIRE_MEMORY *)(data))->size);
if(start_address>=0)
break;
else
sleep(1);
}
temp=(THREAD_RESIDENCE_MEMORY *)malloc(sizeof(THREAD_RESIDENCE_MEMORY));
strcpy(temp->thread_name,((REQUIRE_MEMORY *)(data))->thread_name);
temp->start_address=start_address;
temp->size=((REQUIRE_MEMORY *)(data))->size;
temp->next=NULL;
pthread_mutex_lock(&CS_THREAD_MEMORY_LIST);
tail_thread_residence_memory_list->next=temp;
tail_thread_residence_memory_list=tail_thread_residence_memory_list->next;
pthread_mutex_unlock(&CS_THREAD_MEMORY_LIST);
sleep(((REQUIRE_MEMORY *)(data))->duration);
WF_release_memory(start_address,((REQUIRE_MEMORY *)(data))->size);
sem_post(&thread_end[i]);
return 0;
}
void WF_insert_freearea(FREEAREA *free_node){
FREEAREA *p;
FREEAREA *p_next;
if(p_free_area_list==NULL)
p_free_area_list=free_node;
else{
p=p_next=p_free_area_list;
while(p_next!=NULL&&free_node->size<p_next->size){
p=p_next;
p_next=p_next->next;
}
if(p_next==NULL)
p->next=free_node;
else
if(p==p_next){
free_node->next=p;
p_free_area_list=free_node;
}
else{
free_node->next=p_next;
p->next=free_node;
}
}
}
void WF_initialize_freearea_list(FREEAREA *init_table,int num){
FREEAREA *temp;
int i;
for(i=0;i<num;i++){
temp=(FREEAREA *)malloc(sizeof(FREEAREA));
temp->start_address=init_table[i].start_address;
temp->size=init_table[i].size;
temp->next=NULL;
WF_insert_freearea(temp);
}
}
int WF_require_memory(int size){
int start_address=-1;
FREEAREA *p_next;
pthread_mutex_lock(&CS_FREEAREA_LIST);
p_next=p_free_area_list;
if(size==p_free_area_list->size){
start_address=p_next->start_address;
p_free_area_list=p_free_area_list->next;
free(p_next);
}
else{
if(size<p_next->size){
start_address=p_next->start_address;
p_next->start_address+=size;
p_next->size-=size;
p_free_area_list=p_free_area_list->next;
WF_insert_freearea(p_next);
}
}
pthread_mutex_unlock(&CS_FREEAREA_LIST);
return (start_address);
}
void WF_release_memory(int start_address,int size){
}
void WF(){
int i=0;
int j=0;
REQUIRE_MEMORY *p;
for(j=0;j<MAX_THREAD;j++){
sem_init(&thread_end[j],0,0);
}
pthread_mutex_init(&CS_THREAD_MEMORY_LIST,NULL);
pthread_mutex_init(&CS_FREEAREA_LIST,NULL);
pthread_mutex_init(&CS_SCREEN,NULL);
printw("Wirst Fit\n");
refresh();
WF_initialize_freearea_list(init_free_area_table,5);
p_thread_require_memory_queue=WF_initialize_require_memory_list(init_thread_require_memory_table,3);
p_thread_residence_memory_list=WF_initialize_thread_residence_memory_list
(init_thread_residence_memory_table,5);
p=p_thread_require_memory_queue;
while(p!=NULL){
pthread_create(&h_thread[i],NULL,WF_thread,p);
i++;
p=p->next;
};
for(j=0;j<MAX_THREAD;j++){
sem_wait(&thread_end[j]);
}
pthread_mutex_lock(&CS_SCREEN);
printw("after all threads have finished:\n");
refresh();
display_thread_residence_memory_list();
pthread_mutex_unlock(&CS_SCREEN);
FF_delete_freearea_list();
FF_delete_require_memory_list();
FF_delete_thread_residence_memory_list();
for(j=0;j<MAX_THREAD;j++){
sem_destroy(&thread_end[j]);
}
getch();
printw("\n");
refresh();
}
【测试结果】
来源:https://blog.csdn.net/qq_41587612/article/details/98671028