内存管理模拟

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#define process_num 100						//随机生成的进程数量
#define similize_time 10000					//仿真时长
#define total_size  1024					//存储大小
#define process_max_size 200				//进程占用最大内存大小
#define process_max_time 1000				//进程占用的最长时间
#define error_address total_size+1			//无效地址
typedef struct process process;
typedef struct memlist memlist;
struct process {
	long unsigned int coming_time;
	int running_time;
	unsigned int size;
};
struct memlist {
	unsigned int addr;
	unsigned int size;
	int using_time;
	memlist *next;
};
process* undo;
memlist free_head;				//保存没有被占用的内存块,链表形式
memlist using_head;				//保存正在占用的内存块,链表形式
void random_process();
void similize_process();
void sim_free();
unsigned int sim_alloc(process A);
memlist*best_fit(unsigned int size);
memlist*worst_fit(unsigned int size);
int main() {
	undo = (struct process*)malloc(sizeof(process)*process_num);
	random_process();
	similize_process();
	return 0;
}

void random_process() {//生成随机进程的记录表,输出到process文件中,将undo数组按时间按输入的时间排列
	long unsigned int coming_time;
	int running_time;
	unsigned int size;
	process tmp;
	int i = 0;
	int j = 0;
	int k = 0;
	int undo_size = 0;
	FILE* fp;
	fp = fopen("process.txt", "w");
	//srand((unsigned)time(NULL));
	coming_time = rand() % similize_time;
	running_time = rand() % process_max_time;
	size = rand() % process_max_size;
	undo[0].coming_time = coming_time;
	undo[0].running_time = running_time;
	undo[0].size = size;
	while (undo_size < process_num - 1) {
		coming_time = rand() % similize_time;
		running_time = rand() % process_max_time;
		size = rand() % process_max_size;
		tmp.coming_time = coming_time;
		tmp.running_time = running_time;
		tmp.size = size;
		j = 0;
		while (j <= undo_size && j < process_num&&tmp.coming_time > undo[j].coming_time) {
			j++;
		}
		k = undo_size;
		while (k >= 0 && k >= j) {
			undo[k + 1] = undo[k];
			k--;
		}
		undo[j] = tmp;
		undo_size = undo_size + 1;
	}
	while (i < process_num) {
		fprintf(fp, "%d:coming time %d, running time %d, size %dKB\n", i,
			undo[i].coming_time, undo[i].running_time, undo[i].size);
		i++;
	}
	if (fp) fclose(fp);
	return;
}

void similize_process() {
	FILE*fp;
	fp = fopen("sim_worst.txt", "w");
	memlist *test_p;
	int max_use = 0, use;
	unsigned long sim_time = 0;
	unsigned int address;
	int i = 0;
	int last_deny = 0;
	int accept_time = 0;
	int deny_time = 0;
	free_head.addr = 0;
	free_head.next = (memlist*)malloc(sizeof(memlist));
	free_head.size = 0;
	free_head.using_time = 0;							//初始化链表头,起始时只有一个元素,是全地址,内部按地址从小到大排序
	free_head.next->addr = 0;							//初始化链表,使内存皆为未占用,内部按地址从小到大排序
	free_head.next->next = NULL;
	free_head.next->size = total_size;
	free_head.next->using_time = 0;
	using_head.addr = 0;
	using_head.next = NULL;
	using_head.size = 0;
	using_head.using_time = 0;
	while (sim_time < similize_time)
	{
		sim_time = sim_time + 1;						//向后推时间
		sim_free();										//推进每一个进程,回收并且合并
		if (sim_time < undo[i].coming_time);
		else {
			while (sim_time >= undo[i].coming_time) {
				address = sim_alloc(undo[i]);			//分配,分配成功返回分配的内存地址,分配失败则返回error_address
				if (address == error_address) {
					if (i != last_deny) {
						deny_time++;
						last_deny = i;
						fprintf(fp, "at %d ,process %d is denied\n", sim_time, i);
					}
					break;
				}
				else {
					fprintf(fp, "at %d ,process %d is accepted\n", sim_time, i);
					accept_time++;
				}
				i++;
			}

		}
		printf("%d\n", sim_time);
		test_p = free_head.next;
		use = 0;
		while (test_p != NULL) {
			use += test_p->size;
			test_p = test_p->next;
		}
		if (total_size - use > max_use)
			max_use = total_size - use;
	}
	fprintf(fp, "total deny time %d\ntotal accept time %d\nuse max %dMB", deny_time, accept_time, max_use);
	fclose(fp);
	system("pause");
	return;
}
void sim_free() {																		//推进每一个进程,回收并且合并内存单元
	memlist*p_f, *p_u, *tmp, *p_u_insert, *p_u_back;								
	p_f = &free_head;
	p_u = using_head.next;
	p_u_back = &using_head;
	p_u_insert = NULL;
	tmp = NULL;
	while (p_u != NULL) {
		p_u->using_time = p_u->using_time - 1;											//向后推时间
		if (p_u->using_time <= 0) {
			p_u->using_time = 0;
			p_u_insert = (memlist*)malloc(sizeof(memlist));
			*p_u_insert = *p_u;
			while (p_f->next != NULL && p_f->next->addr < p_u->addr) {
				p_f = p_f->next;														//找到应该回收的位置
			}
			if (p_f->next != NULL && p_u_insert->addr + p_u_insert->size == p_f->next->addr) {//将回收的内存进行拼接,先尝试将刚释放的节点和后面节点相拼接
				p_f->next->addr = p_u_insert->addr;
				p_f->next->size = p_f->next->size + p_u_insert->size;
				free(p_u_insert);
				if (p_f->addr + p_f->size == p_f->next->addr&&p_f != &free_head) {			//如果可以和后面节点相拼接,则尝试前后两个节点是否可以相连
					p_f->size = p_f->size + p_f->next->size;
					tmp = p_f->next;
					p_f->next = tmp->next;
					free(tmp);																			
				}
			}
			else if (p_f != &free_head&&p_f->addr + p_f->size == p_u_insert->addr) {	//不能向后拼接,则向前拼接
				p_f->size = p_f->size + p_u_insert->size;
				free(p_u_insert);
			}
			else {																		//如果内存块不相接则将这块地址插入free_list
				p_u_insert->next = p_f->next;
				p_f->next = p_u_insert;
			}
			tmp = p_u;																	//删除usinglist中的当前节点,防止重复释放
			p_u = p_u->next;
			free(tmp);
			p_u_back->next = p_u;
		}
		else {
			p_u = p_u->next;
			p_u_back = p_u_back->next;
		}
	}
}
unsigned int sim_alloc(process A) {			 // 输入进程,返回被分配的地址位置,如果无法分配内存,则将error_address返回
	memlist *p_f, *p_u, *tmp;
	p_u = NULL;
	//p_f = best_fit(A.size);					//得到的链表项的下一项是应该分配的内存块,否则不利于对链表的释放
	p_f = worst_fit (A.size);
	if (p_f != NULL) {						//产生新的using_mem 块,并且插入using_list
		p_u = (memlist*)malloc(sizeof(memlist));
		p_u->addr = p_f->next->addr;
		p_u->size = A.size;
		p_u->using_time = A.running_time;
		p_u->next = NULL;
		p_f->next->addr = p_f->next->addr + A.size;
		p_f->next->size = p_f->next->size - A.size;
		if (p_f->next->size == 0 && p_f != &free_head) {
			tmp = p_f->next->next;
			free(p_f->next);
			p_f->next = NULL;
		}
		tmp = &using_head;
		while (tmp->next != NULL && tmp->next->addr < p_u->addr) {
			tmp = tmp->next;
		}
		p_u->next = tmp->next;
		tmp->next = p_u;
		return p_u->addr;
	}
	else {
		return error_address;
	}
}

/*以下为两个确定应该使用哪一个内存块的选择算法*/
memlist*best_fit(unsigned int size) {
	memlist *p_f, *result;
	unsigned int dif = total_size;
	unsigned int tmp_dif;
	result = NULL;
	p_f = &free_head;
	while (p_f->next != NULL) {
		tmp_dif = p_f->next->size - size;
		if (tmp_dif < 0 || tmp_dif >= dif);
		else {
			dif = tmp_dif;
			result = p_f;
		}
		p_f = p_f->next;
	}
	return result;

}
memlist*worst_fit(unsigned int size) {
	memlist *p_f, *result;
	unsigned int max = 0;
	result = NULL;
	p_f = &free_head;
	while (p_f->next != NULL) {
		if (p_f->next->size > max&&p_f->next->size >= size) {
			max = p_f->next->size;
			result = p_f;
		}
		p_f = p_f->next;
	}
	return result;
}


/*test program 测试是否正确生成了随机进程列*/
//int main() {
//	int i = 0;
//	undo = (process*)malloc(sizeof(process)*process_num);
//	random_process();
//	system("pause");
//	return 0;
//}

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值