首次适配算法

来源:互联网 发布:arm嵌入式linux系统 编辑:程序博客网 时间:2024/06/05 11:36

假设内存容量为256KB,并且划分成2KB大小的块,即每个内存单元为2KB。规定一个进程所需要的内存为3到10个单元。同时假设一个作业在运行过程中所需内存的大小不变。

1.        用你熟悉的程序设计语言编写和调试一个内存分配和回收的模拟程序,可以参考网络,但是要按要求提交实验作业;

2.        实验报告中必须包括:

首次适配算法:

1)       数据结构的设计和定义(包括详细说明)

typedef struct node{       int address;  //起始地址       int length;   //所占单元长度       int pid;      //标识符 (若是空闲单元则无需标识)       struct node*next;  //链指针}Link;


2)       算法的设计思路和具体处理流程(文字加图形的方式描述)

两个链表,一个分配链表,标识符为进程pid;一个空闲链表,任意节点回收(按pid)。一个记录碎片数。

3)       源代码

/*** * program:内存管理之首次适配算法 * author: 林源 * date :2014.12.5 * */#include<stdio.h>#include<stdlib.h>#define N 128;  //内存单元总大小 (256/2)typedef struct node{int address;  //起始地址int length;   //所占单元长度 int pid;      //标识符 struct node *next;  //链指针 }Link;Link *process,*tail;  //分配进程链表指针 Link *free_node;   //空闲链表指针 /*输出函数*/void prt(){   Link *p = process;  //一个指向当前进程的指针    printf("(开始地址,长度,进程id)");   while(p!=NULL)   {      printf(" %3d%4d%3d --->",p->address,p->length,p->pid);      p=p->next;   }   printf("null");   printf("\n");   Link *f = free_node;  //输出空闲队列    printf("(开始地址,空闲长度)");   while(f!=NULL)   {           printf(" %3d%4d --->",f->address,f->length);      f=f->next;   }   printf("null");   printf("\n");}int search(Link *p){               Link *f = free_node;while(f!=NULL){if(f->length >= p->length)  return f->address;      //找到满足的空闲单元,返回该单元地址          else{               f = f->next;            //若没有则找下一个         } }return 0;                      //没有可用的空闲单元,返回0 }void insert(Link *p,int addr){   Link *f = free_node,*f_before,*pro=process,*pro_beofre;   while(pro!=NULL){     if(pro->address > p->address){      if(pro==process){    //第一个进程单元前面增加     p->next = pro;    process = p;    }else{             //在中间增加       p->next = pro;      pro_beofre->next = p;      }      break;     }else{      pro_beofre = pro;      pro=pro->next;     }   }   if(pro == NULL){         tail->next=p;  //将新的分配进程插入在当前就绪队列的尾       tail=p;      p->next=NULL;   }   while(f!=NULL){    if(f->address == addr){   //修改被插入的空闲单元   f->address = p->address + p->length;    f->length = f->length - p->length;    if(f->length == 0){  if(f == free_node)     free_node = free_node->next;           else         f_before->next = f->next;    free(f);    }    break;  }else {f_before = f;f=f->next;}     }}int judge_exist(int id){Link *p = process;while(p!=NULL){if(p->pid == id){printf("这个进程已经存在,请重新输入.\n");return 1;}else   p=p->next;}return 0;}void create(){   Link *p; //一个指向当前运行进程的指针   int pid,length,address;   p = (Link *)malloc(sizeof(Link));   do{     printf("输入进程pid(唯一标识,不能重复),应分配的内存单元:");      scanf("%d",&pid);      scanf("%d",&length);      p->pid=pid;      p->length=length;   }while(judge_exist(pid));      if((address = search(p)) != 0){     p->address=address;   }else{    printf("已没有可用的空闲单元,请先回收进程\n");    return;    }       if(process!=NULL)  insert(p,address);  //process第一次不为空插入(第一次除外)    else{   //第一次     p->address =1;  p->next=process;       process=p;     tail=p;   //队尾指针      Link *f = free_node;     f->address = p->address + p->length;     f->length = f->length - p->length;        }  }Link* searchP(int id){Link *p = process,*p_before;while(p!=NULL){if(p->pid == id){if(p == process){    //查找的进程刚好是第一个进程        process = process->next;} else{              //不是第一个进程  p_before->next = p->next;if(p->next == NULL) tail = p_before;   //若是最后一个,更新队尾指针  }return p;      //找到进程 }else{    p_before = p;  //正在验证的进程的上一个 p=p->next; } }printf("没有搜索到相应的进程\n");return NULL;}void insert_free_node(Link *p){Link *f = free_node,*f_before,*f1;while(f!=NULL){if(p->address < f->address){if(f == free_node){   //比第一个空闲单元的地址小 if(f->address == p->address+p->length){  //地址+长度刚好等于第一个地址 f->address = p->address;f->length = f->length + p->length;} else{   //地址+长度不等于第一个地址,需增加空闲节点 f1 = (Link *)malloc(sizeof(Link));f1->address = p->address;f1->length = p->length;f1->next = f;f = f1;free_node = f;}return;}else if(f->address == p->address+p->length && f_before->address+f_before->length == p->address){//要释放的进程单元刚好为两个空闲单元的中间且长度等于两个空闲节点之间的长度 f_before->length = f->length + p->length+f_before->length;f_before->next=f->next;    free(f); }else if(f->address == p->address+p->length && f_before->address+f_before->length != p->address){f->address = p->address;f->length = f->length + p->length;}else if(f->address != p->address+p->length && f_before->address+f_before->length == p->address){f_before->length = p->length+f_before->length;}else if(f->address != p->address+p->length && f_before->address+f_before->length != p->address){f1 = (Link *)malloc(sizeof(Link));f1->address = p->address;f1->length = p->length;f1->next = f;f_before->next = f1;}return;}else{  //查找下一个地址比p大的节点 f_before = f;   //记录下个要查找节点的上一个 f = f->next;}}}void recycle(){int pid;Link *p;do{printf("输入回收进程的pid: ");scanf("%d",&pid);p = searchP(pid); }while(p==NULL);        //需输入正确的进程pid insert_free_node(p);   //插入空闲单元 free(p);               }int return_count(){int count=0;  //碎片数    Link* f= free_node;   while(f!=NULL)   {          if(f->length < 3) //空闲单元小于3为一个碎片数          count++;      f=f->next;   }   return count;}int main(){int n;  free_node = (Link *)malloc(sizeof(Link));free_node->address = 1;free_node->length = N;free_node->next = NULL;process = NULL;printf("------------首次适配-------------\n");printf("1.创建进程\n");printf("2.回收进程\n");printf("3.显示内存单元情况\n");printf("4.统计显示碎片数,搜索次数\n");printf("请选择操作(输入命令数字即可,-1退出):");while(scanf("%d",&n)){if(n==-1)break;switch (n){case 1 : create(); break;     case 2 : recycle(); break;case 3 :  prt();     break;  case 4 :  printf("碎片数有:%d\n",return_count());  break;}   printf("请选择操作(输入命令数字即可,-1退出):");} return 0;}


4)       测试数据和运行结果



 

5)       实现代码的不足

在代码实现时,没实现若已用完内存资源,空闲链表为空,回收之-后重新生成空闲的链表

0 0