操作系统课程设计实验报告
设计题目三:动态多分区存储管理模拟系统
——
一、设计题目要求
1、对理论课中学习的内存管理当中的概念做进一步的理解;
2、了解内存管理任务的主要实现方法;
3、掌握内存的分配,回收等主要算法的原理;
4、通过编程,熟悉分区式存储管理方法中内存分配回收算法的实现方法。
二、程序设计思路及流程图
程序功能简介:
主存分配函数:寻找空闲分区,空闲分区表的修改,已分配分区表的修改。其中,若寻找到的最小适合空间相对作业请求的空间来说仍过大,则要分割该分区。
主存回收函数:回收作业释放的分区、修改已分配分区表、修改空闲分区表。其中,若回收的分区有上邻空闲分区或(和)下邻空闲分区的,要合并成为一个空闲分区,登记在空闲分区表的一个表项里。
程序设计思路:
(1)设计一个用来记录主存使用情况的数据结构,登记空闲区和作业区占用的情况;
(2)在设计好的该数据结构上面,再设计一个主存分配算法;
(3)在设计好的该数据结构上面,再设计一个主存回收算法。
开始时,纠结于使用什么数据结构来构建空闲分区表和一个分配表,很明显的是,链表比静态的数组更好一点。但是在思考链表的使用时,竟然错误地定义了两种类型的链表,其实没有必要的,因为这两个表的内容是相同的,一个类型就可以了。这我也是第一次在一个程序里面声明两个链表,对两个链表进行操作。
程序流程图:
见附录A
三、涉及的背景知识及所用函数简介
1、malloc函数
函数原型 :void *malloc(unsigned int num_bytes);
头文件 :stdlib.h
作用 :分配长度为num_bytes字节的内存块
返回值 :分配成功则返回指向被分配内存的指针,否则返回空指针NULL。
2、freopen函数
函数原型 :FILE *freopen(char *filename ,char *type,FILE *stream);
头文件 :stdio.h
作用 :替换一个流,或者说重新分配文件指针,实现重定向。
参数 :filename:要打开的文件名
stream:文件指针,通常使用标准流文件
返回值 :成功返回参数文件指针。
3、strcmp函数
函数原型 :extern int strcmp(const char *s1,const char *s2);
头文件 :string.h
作用 :比较字符串s1和s2
参数 :s1:第一个字符串
s2:第二个字符串
返回值 :如果s1小于s2,返回负数;如果s1大于s2,返回正数;二者相等 返回0.
4、strcpy 函数
函数原型 :extern char strcpy(char dest,const char src);
头文件 :string,h
作用 :把从src地址开始且含有NULL结束符的字符串复制到已dest开始 的地址空间
参数 :scr:原串
Dest:目标串
返回值 :目标串的地址
四、程序所用数据结构简介
int choose :选择要进行的操作;
#define total_size 128:磁盘的总大小;
typedef struct node
{
char name[5];
float address;
float length;
int flag;
struct node *next;
}node, *pnode;
定义结点类型;
typedef struct
{
node *head;
}linklist, *plinklist;
定义链表类型;
linklist used_table, free_table;声明两条链表;
plinklist pused_table, pfree_table; 声明两个指向链表的指针;
void system_init(); 初始化系统,创建两条链表;
plinklist create_list_in_head(); 创建链表;
void insert_node_address_asc(plinklist pl, pnode item);按地址升序在链表中插入结点;
void insert_node_length_asc(plinklist pl, pnode item);按空间大小升序在链表中插入结点;
void insert_node_length_desc(plinklist pl, pnode item);按空间大小降序在链表中插入结点;
void delete_node_in_list(plinklist pl, pnode item);从链表中删除结点;
void display_node_in_list(plinklist pl);显示链表中的所有结点;
void ff();调用首次适应算法ff;
void bf();调用最佳适应算法bf;
void wf();调用最坏适应算法为wf;
五、程序源代码
见附录B
六、调试方案及调试过程记录与分析
输入文件选取:
本程序共3个输入文件,每种算法分别对应一个txt测试数据,见附录B。
输入数据的处理:
采用重定向输入法freopen(“in.txt”, “r”, stdin);
即改变输入路径,不从键盘上输入,而是从文件中读取;
因此,在主函数中只能有一次选择使用哪种算法,若要再次选择其他算法,则需再次输入命令./main。
测试结果、调试过程:
第一次测试结果:文件数据读取错误,数据读取错位。
第一次调试:去掉while(1),重新执行,文件可以正常读取。
第二次测试结果:输出结果陷入死循环。
第二次调试:接受数据的elem变量在接收完一次数据之后没有做初始化处理。
第三次测试结果:结果可以正常输出,但wf算法,并未按空间大小降序排列。
第三次调试:在合并分区时,借用临时变量存储curr。
第四次测试结果:合并可以正常运行,经测试,三种算法均正常执行,结果也是正确的。
七、思考与体会
这次写代码时,没有备份,一不小心把代码全部用rm命令删除了,当时真是欲哭无泪,白辛苦了这么长时间,就这样被自己毁了,还好,用了一个上午重新写了一下,血的教训呀!
要熟练掌握链表的操作,插入,删除。注意特殊情况的处理,比如prev为空时;遍历结束,curr为空时;链表中没有结点时,只有一个结点时,都要认真考虑。
合并的原则:即在物理空间上,地址连续的可以进行合并。
在bf,wf实现时,分区的合并处理,对elem的影响时时变化,所以elem得值也要时时改变,否则,会出现相邻分区未合并的情况。
程序源代码:
源文件名:main.c
内容:/
*************************************************************************
> File Name: main.c
> Author:
> Mail:
>CreatedTime:2014年10月24日 星期五 10时35分43秒************************************************************************/
#include"linklist.h"
int main(void)
{
int choose;
// while(1)//
// {
printf("Welcome!But you should konw that you can run one time. If you want to run again, please input ./main again.\n");
printf("******1.First Fit 2.Best fit *******\n");
printf("******3.Worst Fit 4.exit *******\n");
printf("Please choose the case(1-4):\n");
scanf("%d", &choose);
system_init();
switch(choose)
{
case 1:
ff();
break;
case 2:
bf();
break;
case 3:
wf();
break;
case 4:
exit(0);
default:
printf("Your input is wrong, please input again!\n");
}
// }
return 0;
}
/*************************************************************************
> File Name: linklist.c
> Author:
> Mail:
> Created Time: 2014年10月24日 星期五 10时 30分53秒
************************************************************************/
#include"linklist.h"
plinklist create_list_in_head()
{
plinklist pl = (linklist *)malloc(sizeof(linklist));
pl->head = NULL;//init the head node;
return pl;
}
void system_init()
{
pused_table = create_list_in_head();
pfree_table = create_list_in_head();
pnode item = (node *)malloc(sizeof(node));
item->next = NULL;
item->length = total_size;
item->address = 0;
item->flag = 0;
strcpy(item->name, "pf");
pfree_table->head =item;
printf("List:pfree_table:\n");
display_node_in_list(pfree_table);
return ;
}
void insert_node_address_asc(plinklist pl, pnode item)
{
pnode curr, prev;
if(pl->head == NULL)
{
item->next = pl->head;
pl->head = item;
return;
}
for(curr = pl->head, prev = NULL; curr != NULL; prev = curr, curr = curr->next)
{
if(item->address <= curr->address)
{
if(prev == NULL)
{
item->next = curr;
pl->head = item;
return;
}
else
{
break ;
}
}
}
item->next = curr;
prev->next = item;
return ;
}
void insert_node_length_asc(plinklist pl, pnode item)
{
pnode curr, prev;
if(pl->head == NULL)
{
item->next = pl->head;
pl->head = item;
return;
}
for(curr = pl->head, prev = NULL; curr != NULL; prev = curr, curr = curr->next)
{
if(item->length < curr->length)
{
if(prev == NULL)
{
item->next = curr;
pl->head = item;
return;
}
else
break;
}
}
item->next = curr;
prev->next = item;
return ;
}
void insert_node_length_desc(plinklist pl, pnode item)
{
pnode curr, prev;
if(pl->head == NULL)
{
item->next = pl->head;
pl->head = item;
return ;
}
for(curr = pl->head, prev = NULL; curr != NULL; prev = curr, curr = curr->next)
{
if(item->length > curr->length)
{
if(prev == NULL)
{
item->next = curr;
pl->head = item;
return;
}
else
break;
}
}
item->next = curr;
prev->next = item;
return;
}
void delete_node_in_list(plinklist pl, pnode item)
{
pnode curr, prev;
if(pl->head == NULL)
{
printf("the list is null!\n");
return;
}
for(curr = pl->head, prev = NULL; curr != NULL; prev = curr, curr = curr->next)
{
if(strcmp(curr->name, item->name) == 0)
{
if(prev == NULL)
{
pl->head = curr->next;
}
else
prev->next = curr->next;
return;
}
}
printf("Cannot find the nodeitem!\n");
return ;
}
void display_node_in_list(plinklist pl)
{
pnode p = pl->head;
int i = 0;
while(p)
{
printf("display_node[%d]:%s\t%f\t%f\n", i, p->name, p->address, p->length);
p = p->next;
i++;
}
return ;
}
/*************************************************************************
> File Name: ff.c
> Author:
> Mail:
> Created Time: 2014年10月24日 星期五 10时44分30秒
************************************************************************/
#include"linklist.h"
void ff()
{
pnode elem = (pnode)malloc(sizeof(node));
freopen("ff.txt", "r", stdin);
// freopen("ffout.txt", "w", stdout);
while(scanf("%s%f%d", elem->name, &elem->length, &elem->flag) != EOF)
{
printf("\nRead from the ff.txt:\t%s\t%f\t%d\n", elem->name, elem->length, elem->flag);
if(elem->flag == 0)//distribute ;
{
pnode curr, prev;
for(curr = pfree_table->head, prev = NULL; curr != NULL; prev = curr, curr = curr->next)//scan the free_table;
{
if(curr->length >= elem->length)//find a free_table node;
{
elem->address = curr->address;
elem->flag = 1;
elem->next = NULL;
if(curr->length > elem->length)//divide;
{
insert_node_address_asc(pused_table, elem);
curr->length -= elem->length;
curr->address += elem->length;
break;
}
else
{
insert_node_address_asc(pused_table, elem);
delete_node_in_list(pfree_table, curr);
break;
}
}//if
}//for
}
else//free the used_table;
{
pnode curr, prev;
for(curr = pused_table->head, prev = NULL; curr != NULL; prev = curr, curr = curr->next)//scan the used_table node;
{
if(strcmp(elem->name, curr->name) == 0)
{
elem->address = curr->address;//**
elem->flag = 0;
elem->next = NULL;
insert_node_address_asc(pfree_table, elem);
delete_node_in_list(pused_table, elem);
break;
}
}//for
//merge;
pnode c, p;
for(c = pfree_table->head, p = NULL; c!= NULL; p = c, c = c->next)
{
if(strcmp(elem->name, c->name) == 0)
{
if(p == NULL)
{
if(c->address + c->length == (c->next)->address)
{
c->next->length += c->length;
c->next->address = c->address;
delete_node_in_list(pfree_table, c);
break;
}
}
else if(c->next == NULL)
{
if(p->address + p->length == c->address)
{
c->address = p->address;
c->length += p->length;
delete_node_in_list(pfree_table, p);
break;
}
}
else
{
if(p->address + p->length + c->length == c->next->address)
{
c->next->address = p->address;
c->next->length += p->length + c->length;
delete_node_in_list(pfree_table, p);
delete_node_in_list(pfree_table, c);
break;
}
}
}//if
}//for
}//else
printf("The two list:\n");
printf("List1:pfree_table:\n");
display_node_in_list(pfree_table);
printf("List2:pused_table:\n");
display_node_in_list(pused_table);
elem = (pnode)malloc(sizeof(node));//***
}//while
return ;
}
/*************************************************************************
> File Name: bf.c
> Author:
> Mail:
> Created Time: 2014年10月24日 星期五 10时45分59秒
************************************************************************/
#include"linklist.h"
void bf()
{
pnode elem = (pnode)malloc(sizeof(node));
freopen("bf.txt", "r", stdin);
// freopen("bfout.txt", "w", stdout);
while(scanf("%s%f%d", elem->name, &elem->length, &elem->flag) != EOF)
{
printf("\nRead from the bf.txt:\t%s\t%f\t%d\n", elem->name, elem->length, elem->flag);
if(elem->flag == 0)//distribute ;
{
pnode curr, prev;
for(curr = pfree_table->head, prev = NULL; curr != NULL; prev = curr, curr = curr->next)//scan the free_table;
{
if((*curr).length >= elem->length)//find the first free_table node;
{
elem->address = curr->address;
elem->flag = 1;
elem->next = NULL;
if(curr->length > elem->length)//divide;
{
insert_node_length_asc(pused_table, elem);
curr->length -= elem->length;
curr->address += elem->length;
pnode item = (pnode)malloc(sizeof(node));
*(item) = *(curr);
item->next = NULL;
delete_node_in_list(pfree_table, curr);
insert_node_length_asc(pfree_table, item);
break;
}
else
{
insert_node_length_asc(pused_table, elem);
delete_node_in_list(pfree_table, curr);
break;
}
}
}
}
else//free the used_table;
{
pnode curr, prev;
for(curr = pused_table->head, prev = NULL; curr != NULL; prev = curr, curr = curr->next)//scan the used_table node;
{
if(strcmp(elem->name, curr->name) == 0)
{
elem->flag = 0;
elem->address = curr->address;
elem->next = NULL;
insert_node_length_asc(pfree_table, elem);
delete_node_in_list(pused_table, curr);
break;
}
}
//merge;
pnode c, p;
for(c = pfree_table->head, p = NULL; c!= NULL; p = c, c = c->next)
{
if(c->address + c->length == elem->address)
{
c->length += elem->length;
delete_node_in_list(pfree_table, elem);
pnode item = (pnode)malloc(sizeof(node));
*(item) = *(c);
item->next = NULL;
delete_node_in_list(pfree_table, c);
insert_node_length_asc(pfree_table, item);
*(elem) = *(item);
elem->next = NULL;
}
if(elem->address + elem->length == c->address)
{
c->address = elem->address;
c->length += elem->length;
delete_node_in_list(pfree_table, elem);
pnode item = (pnode)malloc(sizeof(node));
*(item) = *(c);
item->next = NULL;
delete_node_in_list(pfree_table, c);
insert_node_length_asc(pfree_table, item);
*(elem) = *(item);
elem->next = NULL;
}
}//for
}//else
printf("The two list:\n");
printf("List1:pfree_table:\n");
display_node_in_list(pfree_table);
printf("List2:pused_table:\n");
display_node_in_list(pused_table);
elem = (pnode)malloc(sizeof(node));
}
return ;
}
/*************************************************************************
> File Name: wf.c
> Author:
> Mail:
>CreatedTime:2014年10月24日 星期五 10时46分27秒
************************************************************************/
#include"linklist.h"
void wf()
{
pnode elem = (pnode)malloc(sizeof(node));
freopen("wf.txt", "r", stdin);
// freopen("wfout.txt", "w", stdout);
while(scanf("%s%f%d", elem->name, &elem->length, &elem->flag) != EOF)
{
printf("\nRead from the wf.txt:\t%s\t%f\t%d\n", elem->name, elem->length, elem->flag);
if(elem->flag == 0)//distribute ;
{
pnode curr, prev;
for(curr = pfree_table->head, prev = NULL; curr != NULL; prev = curr, curr = curr->next)//scan the free_table;
{
if((*curr).length >= elem->length)//find the first free_table node;
{
elem->address = curr->address;
elem->flag = 1;
insert_node_length_desc(pused_table, elem);
curr->length -= elem->length;
curr->address += elem->length;
pnode item = (pnode)malloc(sizeof(node));
*(item) = *(curr);
item->next = NULL;
delete_node_in_list(pfree_table, curr);
insert_node_length_desc(pfree_table, item);
break;
}
else
{
insert_node_length_desc(pused_table, elem);
delete_node_in_list(pfree_table, curr);
break;
}
}
}
else//free the used_table;
{
pnode curr, prev;
for(curr = pused_table->head, prev = NULL; curr != NULL; prev = curr, curr = curr->next)//scan the used_table node;
{
if(strcmp(elem->name, curr->name) == 0)
{
elem->flag = 0;
elem->address = curr->address;
elem->next = NULL;
printf("elem->address = %f\n", elem->address);
insert_node_length_desc(pfree_table, elem);
delete_node_in_list(pused_table, curr);
break;
}
}
//merge;
pnode c, p;
for(c = pfree_table->head, p = NULL; c!= NULL; p = c, c = c->next)
{
if(c->address + c->length == elem->address)
{
c->length += elem->length;
delete_node_in_list(pfree_table, elem);
pnode item = (pnode)malloc(sizeof(node));
*(item) = *(c);
item->next = NULL;
delete_node_in_list(pfree_table, c);
insert_node_length_desc(pfree_table, item);
*(elem) = *(item);
elem->next = NULL;
}
if(elem->address + elem->length == c->address)
{
c->address = elem->address;
c->length += elem->length;
delete_node_in_list(pfree_table, elem);
pnode item = (pnode)malloc(sizeof(node));
*(item) = *(c);
item->next = NULL;
delete_node_in_list(pfree_table, c);
insert_node_length_desc(pfree_table, item);
*(elem) = *(item);
elem->next = NULL;
}
}//for
}//else
printf("The two list:\n");
printf("List1:pfree_table:\n");
display_node_in_list(pfree_table);
printf("List2:pused_table:\n");
display_node_in_list(pused_table);
elem = (pnode)malloc(sizeof(node));
}
return ;
}
/*************************************************************************
> File Name: linklist.h
> Author:
> Mail:
> Created Time: 2014年10月24日 星期五 10时45分53秒
************************************************************************/
#ifndef _LINKLIST_H
#define _LINKLIST_H
#include
#include
#include
#include
#define total_size 128
typedef struct node
{
char name[5];
float address;
float length;
int flag;
struct node *next;
}node, *pnode;
typedef struct
{
node *head;
}linklist, *plinklist;
linklist used_table, free_table;
plinklist pused_table, pfree_table;
void system_init();
plinklist create_list_in_head();
void insert_node_address_asc(plinklist pl, pnode item);
void insert_node_length_asc(plinklist pl, pnode item);
void insert_node_length_desc(plinklist pl, pnode item);
void delete_node_in_list(plinklist pl, pnode item);
void display_node_in_list(plinklist pl);
void ff();
void bf();
void wf();
#endif
Makefile:
vpath %.h ./
main: main.o linklist.o ff.o bf.o wf.o linklist.h
gcc -o main main.o linklist.o ff.o bf.o wf.o
main.o:main.c linklist.c ff.c bf.c wf.c linklist.h
gcc -c main.c linklist.c ff.c bf.c wf.c
linklist.o: linklist.c linklist.h
gcc -c linklist.c
ff.o:ff.c linklist.c linklist.h
gcc -c ff.c linklist.c
bf.o:bf.c linklist.c linklist.h
gcc -c bf.c linklist.c
wf.o:wf.c linklist.c linklist.h
gcc -c wf.c linklist.c
测试数据:
ff.txt:
P1 28 0
P2 50 0
P3 24 0
P2 50 1
P4 42 0
P1 28 1
P5 25 0
P6 26 0
P4 42 1
b.txt:
P1 28 0
P2 50 0
P3 24 0
P1 28 1
P4 8 0
P3 24 1
P5 18 0
P4 8 1
wf.txt:
P1 28 0
P2 50 0
P3 24 0
P1 28 1
P4 25 0
P2 50 1
P3 24 1