动态多分区存储管理模拟系统

操作系统课程设计实验报告


设计题目三:动态多分区存储管理模拟系统

——


一、设计题目要求

   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

 

你可能感兴趣的:(操作系统)