存储管理算法设计之【内存空间的分配和回收】

博客总领目录请看这篇,不看后悔

软件工程专业大学四年学什么_大学近代史学分是多少-CSDN博客icon-default.png?t=N7T8https://blog.csdn.net/qq_41587612/article/details/104362661B站同名up猪,欢迎关注我的账号鸽子不二的个人空间-鸽子不二个人主页-哔哩哔哩视频哔哩哔哩鸽子不二的个人空间,提供鸽子不二分享的视频、音频、文章、动态、收藏等内容,关注鸽子不二账号,第一时间了解UP主动态。icon-default.png?t=N7T8https://space.bilibili.com/204913846

设计一  内存空间的分配和回收

【实验目的】

通过本实验,帮助学生理解存储管理的功能,掌握动态异长分区的存储分配与回收算法。

【实验内容】

模拟动态异长分区的分配算法、回收算法。

【实验要求】

常用的动态异长分区的分配算法有:最先适应算法、最佳适应算法和最坏适应算法。要求选择任意一种算法,设计相应的数据结构,模拟内存空间的分配和回收。实验报告中给出程序中使用的数据结构及流程图。

【实验原理】

  • 首次适应算法(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();
}

【测试结果】

2.设计一个虚拟存储区和内存工作区,并使用下述算法计算访问命中率。 1) 最佳置换算法(Optimal) 2) 先进先出(Fisrt In First Out) 3) 最近最久未使用(Least Recently Used) 4) 最不经常使用(Least Frequently Used) 5) 最近未使用(No Used Recently) 其中,命中率=1-页面失效次数/页地址流长度。 试对上述算法的性能加以较各:页面个数和命中率间的关系;同样情况下的命中率比较。 实验准备 本实验中主要的流程:首先用srand( )和rand( )函数定义和产生指令序列,然后将指令序列变换成相应的页地址流,并针对不同的算法计算出相应的命中率。 实验可先从一个具体的例子出发。 (1)通过随机数产生一个指令序列,共2048条指令。指令的地址按下述原则生成: A:50%的指令是顺序执行的 B:25%的指令是均匀分布在前地址部分 C:25%的指令是均匀分布在后地址部分 具体的实施方是: A:在[0,1023]的指令地址之间随机选取一起点m B:顺序执行一条指令,即执行地址为m+1的指令 C:在前地址[0,m+1]中随机选取一条指令并执行,该指令的地址为m’ D:顺序执行一条指令,其地址为m’+1 E:在后地址[m’+2,2047]中随机选取一条指令并执行 F:重复步骤A-E,直到2048次指令 (2)将指令序列变换为页地址流 设:页面大小为4K; 用户内存容量4页到32页; 用户虚存容量为32K。 在用户虚存中,按每K存放64条指令排列虚存地址,即2048条指令在虚存中的存放方式为: 第 0 条-第 63 条指令为第0页(对应虚存地址为[0,63]) 第64条-第127条指令为第1页(对应虚存地址为[64,127]) ……………………………… 第1984条-第2047条指令为第31页(对应虚存地址为[1984,2047]) 按以上方式,用户指令可组成32页。
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值