操作系统第5次实验报告:内存管理

  • 袁祎琦
  • 201821121033
  • 计算1812

内存管理的功能:

1、内存空间的分配与回收:由操作系统完成主存储器空间的分配和管理,使程序员摆脱存储分配的麻烦,提高编程效率。

2、地址转换:在多道程序环境下,程序中的逻辑地址与内存中的物理地址不可能一致,因此存储管理必须提供地址转换功能,把逻辑地址转换成相应的物理地址。

3、内存空间的扩充:利用虚拟内存技术或自动覆盖技术,从逻辑上扩充内存。

4、存储保护:保证各道作业在各自的存储空间内运行,互不干扰。

1. 记录内存空间使用情况

所谓分区,就是分为一些大小相等或不等的分区,除操作系统占用一个分区外,其余分区用来存放进程的程序和数据,本次实验中采用动态分区法。

操作系统对内存的划分和动态分配,就是内存管理的概念。有效的内存管理在多道程序设计中非常重要,不仅方便用户使用存储器、提高内存利用率,还可以通过虚拟技术从逻辑上扩充存储器。

 1 int display_mem_usage(){
 2     //显示当前内存的使用情况,包括空闲分区的情况和已经分配的情况
 3     FBT *fbt = free_block;
 4     AB *ab = allocated_block_head;
 5     printf("\e[0;31;1m------------------------------------------------------------------\e[0m\n");
 6     //显示空闲区
 7     printf("\e[0;32;1mFree Memory:\e[0m\n");
 8     printf("\e[0;33;1m%20s %20s\e[0m\n","     start_addr","       size");
 9     while(fbt!=NULL){
10         printf("%20d %20d\n",fbt->start_addr,fbt->size);
11         fbt = fbt->next;
12     }
13     //显示已分配区
14     printf("\n");
15     printf("\e[0;35;1mUsed Memory:\e[0m\n");
16     printf("\e[0;33;1m%10s %20s %20s %10s\e[0m\n","PID","ProcessName","start_addr","size");
17     while(ab != NULL){
18         printf("%10d %20s %20d %10d\n",ab->pid,ab->process_name,ab->start_addr,ab->size);
19         ab = ab->next;
20     }
21     printf("\e[0;31;1m------------------------------------------------------------------\e[0m\n");
22     return 0;
23 }

2. 记录空闲分区

空闲内存区块表,包含该空闲区的起始地址以及大小。建立空闲分区链表,使之指向内存中空闲块链的首指针。

//描述每一个空闲块的数据结构
typedef struct free_block_type{
    int size;
    int start_addr;
    struct free_block_type *next;
}FBT;

//每个进程分配到的内存块描述
typedef struct allocated_block{
    int pid;
    int size;
    int start_addr;
    char process_name[PROCESS_NAME_LEN];
    struct allocated_block *next;
}AB;

//指向内存中空闲块链表的首指针
FBT *free_block;
//进程分配内存块链表的首指针
AB *allocated_block_head = NULL;
 
//初始化空闲分区链表
FBT *init_free_block(int mem_size){
    FBT *fb;//申请空间
    fb = (FBT*)malloc(sizeof(FBT));
    if(fb==NULL){
        printf("No mem\n");
        return NULL;
    }
    fb->size = mem_size;
    fb->start_addr = DEFAULT_MEM_START;
    fb->next = NULL;
    return fb;
}

空闲分区(free_block_type)结构体解释:size属性表示空闲分区的大小,start_addr表示空闲 分区首地址,next指针指向下一个空闲分区。

已分配内存空间(allocated_block)结构体解释:定义已分配的内存空间的机构提,用来保存已经被进程占用了内存空间的情况。其中,pid作为该被分配分区的编号,用于在释放该内存看空间时便于查找。size表示的分区的大小,start_addr表示分区的起始地址,process_name存放进程名称,next指针指向下一个分区。

3. 内存分配算法

内存分配算法:首先从可用表/自由链中找到一个足以容纳该作业的可用空白区,如果这个空白区比需求大,则将它分为两个部分,一部分称为已分配去,剩下部分仍为空闲区。最后修改可用表或自由链,并回送一个所分配区的序号或该分配区的起始地址。其余的在下面的代码区块中有解释。

内存分配过程(解释在代码中):

  1 //设置内存大小
  2 int set_mem_size(){
  3     int size;
  4     if(flag!=0){
  5         printf("Cannot set memory size again\n");
  6         return 0;
  7     }
  8     printf("Total memory size =");
  9     scanf("%d",&size);
 10     if(size>0){
 11         mem_size = size;
 12         free_block->size = mem_size;
 13     }
 14     flag = 1;
 15     min_mem_size = mem_size / 100;
 16     return 1;
 17 }
 18 
 19 //设置分配算法
 20 void set_algorithm(){
 21     int algorithm;
 22     printf("\t1 - First Fit\n");
 23     printf("\t2 - Best Fit\n");
 24     printf("\t3 - Worst Fit\n");
 25     scanf("%d",&algorithm);
 26     if(algorithm>=1 && algorithm<=3)
 27         ma_algorithm = algorithm;
 28     //按指定算法重新排列空闲区链表
 29     rearrange(ma_algorithm);
 30 }
 31 
 32 //进行内存紧缩
 33 void  memory_compact(){
 34     FBT *fbttmp = free_block;
 35     AB *abtmp = allocated_block_head;
 36     //检测剩余内存
 37     int sum = 0;
 38     while(fbttmp!=NULL){
 39         sum += fbttmp->size;
 40         fbttmp = fbttmp->next;
 41     }
 42     //合并区块为一个
 43     fbttmp = free_block;
 44     fbttmp->size = sum;
 45     fbttmp->start_addr = 0;
 46     fbttmp->next=NULL;
 47     //释放多余分区
 48     FBT *pr = free_block->next;
 49     while(pr != NULL){
 50         fbttmp = pr->next;
 51         free(pr);
 52         pr = fbttmp;
 53     }
 54     //重新排序已分配空间
 55     sort_AB();
 56     reset_AB(sum);
 57 }
 58 
 59 //分配内存模块
 60 int allocate_mem(AB *ab){
 61     FBT *fbt,*pre;
 62     int request_size=ab->size;
 63     fbt = pre = free_block;
 64     //尝试寻找可分配空闲,具体结果在函数中有解释
 65     int f = find_free_mem(request_size);
 66     if(f == -1){
 67         //不够分配
 68         printf("Free mem is not enough,Allocate fail!\n");
 69         return -1;
 70     }else{
 71         if(f == 0){
 72             //需要内存紧缩才能分配
 73             memory_compact();
 74         }
 75         //执行分配
 76         do_allocate_mem(ab);
 77     }
 78     //重新排布空闲分区
 79     rearrange(ma_algorithm);
 80     return 1;
 81 } 
 82 
 83 //执行分配内存模块
 84 void do_allocate_mem(AB *ab){
 85     int request = ab->size;
 86     FBT *tmp = free_block;
 87     while(tmp != NULL){
 88         if(tmp->size >= request){
 89             //分配
 90             ab->start_addr = tmp->start_addr;
 91             int shengyu = tmp->size - request;
 92             if(shengyu <= min_mem_size){
 93                 //剩余过小全部分配
 94                 ab->size = tmp->size;
 95                 if(tmp == free_block){
 96                     free_block = free_block->next;
 97                     free(tmp);
 98                 }else{
 99                     FBT *t = free_block;
100                     while(t->next != tmp){
101                         t = t->next;
102                     }
103                     t->next = tmp->next;
104                     free(tmp);
105                 }
106             }else{
107                 //切割出分配走的内存
108                 tmp->size = shengyu;
109                 tmp->start_addr = tmp->start_addr + request;
110             }
111             return ;
112         }
113         tmp = tmp->next;
114     }
115 }
116 
117 //创建新进程
118 int new_process(){
119     AB *ab;
120     int size;
121     int ret;
122     ab = (AB*)malloc(sizeof(AB));
123     if(!ab) exit(-5);
124     ab->next=NULL;
125     pid++;
126     sprintf(ab->process_name,"PROCESS-%02d",pid);
127     ab->pid = pid;
128     printf("Memory for %s:",ab->process_name);
129     scanf("%d",&size);
130     if(size>0) ab->size=size;
131     ret = allocate_mem(ab);    //从空闲分区分配内存,ret==1表示分配成功
132     if((ret == 1) && (allocated_block_head == NULL)){
133         //如果此时allocated_block_head尚未赋值,则赋值
134         allocated_block_head = ab;
135         return 1;
136     }else if(ret == 1){
137         //分配成功,将该分配块的描述插入已分配链表
138         ab->next = allocated_block_head;
139         allocated_block_head = ab;
140         return 2;
141     }else if(ret == -1){ //分配不成功
142         printf("\e[0;31;1m Allocation fail \e[0m\n");
143         free(ab);
144         return -1;
145     }
146     return 3;
147 }

初始化模块(allocate_mem):设置内存的最大容量,该内存空间的首地址,一遍之后新建进程的过程中使用,当空闲分区初始化失败时,要进行相应的提示。

新建进程模块(new_process):在内存空间中申请一块空间供进程使用,通过输入进程大小,系统先查看内次年空间中是否有足够的空间供其进行申请,若无,则显示分配失败信息,否则在空闲内存分区块中选择最先的一块进行分配,若内存空间不足则继续向下查找,空闲内存分区的顺序通过三种算法给出,分配内存时,要指定进程的首地址和大小,并对空闲分区的大小做相应的修改。

其中,set_algorithm中的算法包括:

1 //按指定的算法整理内存空闲块链表
2 void rearrange(int algorithm){
3     switch(algorithm){
4         case MA_FF:rearrange_FF();break;//首次适应算法
5         case MA_BF:rearrange_BF();break;//最佳算法
6         case MA_WF:rearrange_WF();break;//最坏适应算法
7     }
8 }

三种内存分配算法的特点和不同:

/*
    1、最先适应算法(FF)
    它要求空闲分区表中的记录按地址递增的顺序排列。在每次分配主存时,总是从第一条记录开始顺序查找空闲分区表,找到第一个能满足作业长度要求的空闲区,分隔这个空闲区。一部分分配给作业,另一部分仍作为空闲区。
特点:
    分配算法简单,容易产生过多的主存碎片。主存碎片是指小的不能使用的主存空间;这种算法把大的空闲区分成了小的空闲区,当有大的作业要求分配时,不能满足要求,降低了系统的效率。

    2、最优适应算法(BF)
    它是从所有的空闲分区中挑选一个能满足作业要求的最小空闲区进行分配。这样可以保证不去分割一个更大的空闲区,使装入大作业时比较容易得到满足。为实现这种算法,把空闲区按长度递增次序登记在空闲分区表中,分配时,顺序查找。
特点:
    解决了大作业的分配问题,不足是容易产生主存碎片,降低了主存空间的利用率。另外,回收主存时,要按长度递增顺序插入到空闲分区表中,增加了系统开销。

    3、最坏适应分配算法(WF)
    它每次分配主存时总是挑选一个最大的空闲区,分割一部分给作业使用,使剩下的部分不至于太小而成为主存碎片。为实现这种算法,把空闲区按长度递减的次序登记在空闲分区表中,分配时,顺序查找。
特点:
    不会产生过多的碎片。不足是影响大作业的分配。回收主存时,要按长度递减的顺序插入到空闲分区表中,增加了系统开销。
*/

三种内存分配算法具体实现:

 1 //首次适应算法,空闲区大小按起始地址升序排序
 2 /*
 3    从空前分区表的第一个表目查找该表,把最先能够满足要求的空闲区分配给作业,这种方法的目的在于减少查找时间
 4 */
 5 void rearrange_FF(){
 6     //使用冒泡排序方法
 7     if(free_block == NULL || free_block->next == NULL)
 8         return;
 9     FBT *t1,*t2,*head;
10     head = free_block;
11     for(t1 = head->next;t1;t1 = t1->next){
12         for(t2 = head;t2 != t1;t2=t2->next){
13                     /*空闲分区以地址递增的次序链接,分配内存是顺序查找*/
14             if(t2->start_addr > t2->next->start_addr){
15                 int tmp = t2->start_addr;
16                 t2->start_addr = t2->next->start_addr;
17                 t2->next->start_addr = tmp;
18                 tmp = t2->size;
19                 t2->size = t2->next->size;
20                 t2->next->size = tmp;
21             }
22         }
23     }
24 }
25 //最佳适应算法,空闲分区按大小从小到大排序
26 /*
27     从全部空闲区中找出能满足作业要求的,且大小最小的空闲分区,这种方法能使随便尽量小
28 */
29 void rearrange_BF(){
30     if(free_block == NULL || free_block->next == NULL)
31         return;
32     FBT *t1,*t2,*head;
33     head = free_block;
34     for(t1 = head->next;t1;t1 = t1->next){
35         for(t2 = head;t2 != t1;t2=t2->next){
36                     /*空闲分区按容量递增形成分区链*/
37             if(t2->size > t2->next->size){
38                 int tmp = t2->start_addr;
39                 t2->start_addr = t2->next->start_addr;
40                 t2->next->start_addr = tmp;
41                 tmp = t2->size;
42                 t2->size = t2->next->size;
43                 t2->next->size = tmp;
44             }
45         }
46     }
47 }
48 //最坏适应算法,空闲分区按从大到小排序
49 /*
50     它从全部空闲区中找出能满足作业要求的、且大小最大的空闲enquirer,从而使链表中节点大小趋于均匀
51 */
52 void rearrange_WF(){
53     if(free_block == NULL || free_block->next == NULL)
54         return;
55     FBT *t1,*t2,*head;
56     head = free_block;
57     for(t1 = head->next;t1;t1 = t1->next){
58         for(t2 = head;t2 != t1;t2=t2->next){
59                     /*空闲分区以从良递减的次序链接*/
60             if(t2->size < t2->next->size){ 
61                 int tmp = t2->start_addr;
62                 t2->start_addr = t2->next->start_addr;
63                 t2->next->start_addr = tmp;
64                 tmp = t2->size;
65                 t2->size = t2->next->size;
66                 t2->next->size = tmp;
67             }
68         }
69     }
70 }  

4. 内存释放算法

进程终止,释放内存,如何释放,如何更新内存空闲分区表。给出算法源代码,并解释。

释放过程:找到pid对应的链表节点,释放进程该进程所占用的内存(将进程的已分配区归还,并进行可能的合并,按地址重新品排布),释放链表节点。

 1 //释放链表节点
 2 int dispose(AB *free_ab){
 3     //释放ab数据结构节点
 4     AB *pre,*ab;
 5     if(free_ab == allocated_block_head){
 6         //如果要是释放第一个节点
 7         allocated_block_head = allocated_block_head->next;
 8         free(free_ab);
 9         return 1;
10     }
11     pre = allocated_block_head;
12     ab = allocated_block_head->next;
13     while(ab!=free_ab){
14         pre = ab;
15         ab = ab->next;
16     }
17     pre->next = ab->next;
18     free(ab);
19     return 2;
20 }
21 //释放进程所占用的内存
22 int free_mem(AB *ab){
23     //将ab所表示的已分配区归还,并进行可能的合并 
24     int algorithm = ma_algorithm;
25     FBT *fbt,*pre,*work;
26     fbt = (FBT*)malloc(sizeof(FBT));
27     if(!fbt) return -1;
28     fbt->size = ab->size;
29     fbt->start_addr = ab->start_addr;
30 
31     //插至末尾
32     work = free_block;
33     if(work == NULL){
34         free_block = fbt;
35         fbt->next == NULL;
36     }else{
37         while(work ->next != NULL){
38             work = work->next;
39         }
40         fbt->next = work->next;
41         work->next = fbt;
42     }
43     //按地址重新排布
44     rearrange_FF();
45     //合并可能分区;即若两空闲分区相连则合并
46     pre = free_block;
47     while(pre->next){
48         work = pre->next;
49         if(pre->start_addr + pre->size == work->start_addr ){
50             pre->size = pre->size + work->size;
51             pre->next = work->next;
52             free(work);
53             continue;
54         }else{
55             pre = pre->next;
56         }
57     }
58     //按照当前算法排序
59     rearrange(ma_algorithm);
60     return 1;
61 }
62 //找到pid对应的链表节点
63 AB *find_process(int pid){
64     AB *tmp = allocated_block_head;
65     while(tmp != NULL){
66         if(tmp->pid == pid){
67             return tmp;
68         }
69         tmp = tmp->next;
70     }
71     printf("\e[0;31;1m Cannot find pid:%d \e[0m\n",pid);
72     return NULL;
73 }
74 //删除进程
75 int kill_process(){
76     AB *ab;
77     int pid;
78     printf("Kill Process,pid=");
79     scanf("%d",&pid);
80     ab = find_process(pid);
81     if(ab!=NULL){
82         free_mem(ab);    //释放ab所表示的分配表
83         dispose(ab);    //释放ab数据结构节点
84         return 0;
85     }else{
86         return -1;
87     }
88 }

进程终止模块(kill_process):通过输入对应pid完成对相应进程的终止功能,将其内存空间设置为空闲分区,若与已有空闲分区的地址连续,则进行空闲分区的合并。

5. 运行结果

(1)产生测试数据

写程序,产生测试数据(随机)。给出你的源码,以及你生成的测试数据是什么。

 1 int main(int argc, char const *argv[]){
 2     char choice;
 3     pid = 0;
 4     free_block = init_free_block(mem_size); //初始化空闲区
 5     while(1){
 6         fflush(stdin);
 7         display_menu(); //显示菜单
 8         fflush(stdin);
 9         while((choice = getchar()) != '\n'){
10         //choice = getchar();
11         fflush(stdin);
12         switch(choice){
13             case '1':set_mem_size();break;//设置内存大小
14             case '2':set_algorithm();flag = 1;break;//设置分配算法
15             case '3':new_process();flag = 1;break;//创建新进程
16             case '4':kill_process();flag = 1;break;//删除进程
17             case '5':display_mem_usage();flag = 1;break;//显示内存使用
18             case '0':do_exit();exit(0);//释放链表退出
19             default: break;
20         }
21         fflush(stdin);
22         }
23     }
24 }
25 void display_menu(){
26     puts("");
27     printf("1 - Set memory size(fedault=%d)\n",DEFAULT_MEM_SIZE);
28     printf("2 - Select memory allocation algorithm\n");
29     printf("3 - New process\n");
30     printf("4 - Terminate a process \n");
31     printf("5 - Display memory usage\n");
32     printf("0 - Exit\n");
33 }

测试数据:

 

 

 

 

 

 

 

运行结果:

(2)解释结果

1、设置内存块大小为1024。

2、选择内存分配算法,FF。

3、创建新进程1,PROCESS-01,大小为10。

4、创建新进程2,PROCESS-01,大小为25。

5、设置内存分配算法,BF。

6、创建新进程3,PROCESS-03,大小为50。

7、创建新进程4,PROCESS-04,大小为80。

8、结束一个进程,pid=2。

9、设置内存分配算法,MF。

10、创建新进程5,PROCESS-05,大小为100。

附录(所有源码):

  1 #include<stdio.h>
  2 #include<stdlib.h>
  3 #include "mem.h"
  4 
  5 typedef struct free_block_type{
  6     int size;
  7     int start_addr;
  8     struct free_block_type *next;
  9 }FBT;
 10 
 11 typedef struct allocated_block{
 12     int pid;
 13     int size;
 14     int start_addr;
 15     char process_name[PROCESS_NAME_LEN];
 16     struct allocated_block *next;
 17 }AB;
 18 
 19 FBT *free_block;
 20 AB *allocated_block_head = NULL; 
 21 
 22 int mem_size = DEFAULT_MEM_SIZE;
 23 int ma_algorithm = MA_FF; 
 24 static int pid = 0; 
 25 int flag = 0; 
 26 int min_mem_size = 10; 
 27 
 28 FBT *init_free_block(int mem_size);
 29 void display_menu();
 30 int set_mem_size();
 31 int display_mem_usage();
 32 int dispose(AB *free_ab);
 33 int free_mem();
 34 int kill_process();
 35 int allocate_mem(AB *ab);
 36 int new_process();
 37 void rearrange_FF();
 38 void rearrange_BF();
 39 void rearrange_WF();
 40 void rearrange(int algorithm);
 41 void set_algorithm();
 42 void do_exit(){
 43     return;
 44 }
 45 int main(int argc, char const *argv[]){
 46     char choice;
 47     pid = 0;
 48     free_block = init_free_block(mem_size);
 49     while(1){
 50         fflush(stdin);
 51         display_menu(); 
 52         fflush(stdin);
 53         while((choice = getchar()) != '\n'){
 54 
 55         fflush(stdin);
 56         switch(choice){
 57             case '1':set_mem_size();break;
 58             case '2':set_algorithm();flag = 1;break;
 59             case '3':new_process();flag = 1;break;
 60             case '4':kill_process();flag = 1;break;
 61             case '5':display_mem_usage();flag = 1;break;
 62             case '0':do_exit();exit(0);
 63             default: break;
 64         }
 65         fflush(stdin);
 66         }
 67     }
 68 }
 69 void display_menu(){
 70     puts("");
 71     printf("1 - Set memory size(fedault=%d)\n",DEFAULT_MEM_SIZE);
 72     printf("2 - Select memory allocation algorithm\n");
 73     printf("3 - New process\n");
 74     printf("4 - Terminate a process \n");
 75     printf("5 - Display memory usage\n");
 76     printf("0 - Exit\n");
 77 }
 78 FBT *init_free_block(int mem_size){
 79     FBT *fb;
 80     fb = (FBT*)malloc(sizeof(FBT));
 81     if(fb==NULL){
 82         printf("No mem\n");
 83         return NULL;
 84     }
 85     fb->size = mem_size;
 86     fb->start_addr = DEFAULT_MEM_START;
 87     fb->next = NULL;
 88     return fb;
 89 }
 90 int set_mem_size(){
 91     int size;
 92     if(flag!=0){
 93         printf("Cannot set memory size again\n");
 94         return 0;
 95     }
 96     printf("Total memory size =");
 97     scanf("%d",&size);
 98     if(size>0){
 99         mem_size = size;
100         free_block->size = mem_size;
101     }
102     flag = 1;
103     min_mem_size = mem_size / 100;
104     return 1;
105 }
106 int display_mem_usage(){
107     FBT *fbt = free_block;
108     AB *ab = allocated_block_head;
109     printf("\e[0;31;1m------------------------------------------------------------------\e[0m\n");
110     printf("\e[0;32;1mFree Memory:\e[0m\n");
111     printf("\e[0;33;1m%20s %20s\e[0m\n","     start_addr","       size");
112     while(fbt!=NULL){
113         printf("%20d %20d\n",fbt->start_addr,fbt->size);
114         fbt = fbt->next;
115     }
116     printf("\n");
117     printf("\e[0;35;1mUsed Memory:\e[0m\n");
118     printf("\e[0;33;1m%10s %20s %20s %10s\e[0m\n","PID","ProcessName","start_addr","size");
119     while(ab != NULL){
120         printf("%10d %20s %20d %10d\n",ab->pid,ab->process_name,ab->start_addr,ab->size);
121         ab = ab->next;
122     }
123     printf("\e[0;31;1m------------------------------------------------------------------\e[0m\n");
124     return 0;
125 }
126 int dispose(AB *free_ab){
127     AB *pre,*ab;
128     if(free_ab == allocated_block_head){
129         allocated_block_head = allocated_block_head->next;
130         free(free_ab);
131         return 1;
132     }
133     pre = allocated_block_head;
134     ab = allocated_block_head->next;
135     while(ab!=free_ab){
136         pre = ab;
137         ab = ab->next;
138     }
139     pre->next = ab->next;
140     free(ab);
141     return 2;
142 }
143 int free_mem(AB *ab){
144     int algorithm = ma_algorithm;
145     FBT *fbt,*pre,*work;
146     fbt = (FBT*)malloc(sizeof(FBT));
147     if(!fbt) return -1;
148     fbt->size = ab->size;
149     fbt->start_addr = ab->start_addr;
150 
151     work = free_block;
152     if(work == NULL){
153         free_block = fbt;
154         fbt->next == NULL;
155     }else{
156         while(work ->next != NULL){
157             work = work->next;
158         }
159         fbt->next = work->next;
160         work->next = fbt;
161     }
162     rearrange_FF();
163     pre = free_block;
164     while(pre->next){
165         work = pre->next;
166         if(pre->start_addr + pre->size == work->start_addr ){
167             pre->size = pre->size + work->size;
168             pre->next = work->next;
169             free(work);
170             continue;
171         }else{
172             pre = pre->next;
173         }
174     }
175     rearrange(ma_algorithm);
176     return 1;
177 }
178 AB *find_process(int pid){
179     AB *tmp = allocated_block_head;
180     while(tmp != NULL){
181         if(tmp->pid == pid){
182             return tmp;
183         }
184         tmp = tmp->next;
185     }
186     printf("\e[0;31;1m Cannot find pid:%d \e[0m\n",pid);
187     return NULL;
188 }
189 int kill_process(){
190     AB *ab;
191     int pid;
192     printf("Kill Process,pid=");
193     scanf("%d",&pid);
194     ab = find_process(pid);
195     if(ab!=NULL){
196         free_mem(ab);    
197         dispose(ab);    
198         return 0;
199     }else{
200         return -1;
201     }
202 }
203 int find_free_mem(int request){
204     FBT *tmp = free_block;
205     int mem_sum = 0;
206     while(tmp){
207         if(tmp->size >= request){
208             return 1;
209         }
210         mem_sum += tmp->size;
211         tmp = tmp->next;
212     }
213     if(mem_sum >= request){
214         return 0;
215     }
216     else{
217         return -1;
218     }
219 
220 }
221 void sort_AB(){
222     if(allocated_block_head == NULL || allocated_block_head->next == NULL)
223         return;
224     AB *t1,*t2,*head;
225     head = allocated_block_head;
226     for(t1 = head->next;t1;t1 = t1->next){
227         for(t2 = head;t2 != t1;t2=t2->next){
228             if(t2->start_addr > t2->next->start_addr){
229                 int tmp = t2->start_addr;
230                 t2->start_addr = t2->next->start_addr;
231                 t2->next->start_addr = tmp;
232 
233                 tmp = t2->size;
234                 t2->size = t2->next->size;
235                 t2->next->size = tmp;
236             }
237         }
238     }
239 }
240 void reset_AB(int start){
241     AB *tmp = allocated_block_head;
242     while(tmp != NULL){
243         tmp->start_addr = start;
244         start += tmp->size;
245         tmp = tmp->next;
246     }
247 }
248 void  memory_compact(){
249     FBT *fbttmp = free_block;
250     AB *abtmp = allocated_block_head;
251 
252     int sum = 0;
253     while(fbttmp!=NULL){
254         sum += fbttmp->size;
255         fbttmp = fbttmp->next;
256     }
257     fbttmp = free_block;
258     fbttmp->size = sum;
259     fbttmp->start_addr = 0;
260     fbttmp->next=NULL;
261     
262 
263     FBT *pr = free_block->next;
264     while(pr != NULL){
265         fbttmp = pr->next;
266         free(pr);
267         pr = fbttmp;
268     }
269     sort_AB();
270     reset_AB(sum);
271 
272 }
273 void do_allocate_mem(AB *ab){
274     int request = ab->size;
275     FBT *tmp = free_block;
276     while(tmp != NULL){
277         if(tmp->size >= request){
278 
279             ab->start_addr = tmp->start_addr;
280             int shengyu = tmp->size - request;
281             if(shengyu <= min_mem_size){
282                 ab->size = tmp->size;
283                 if(tmp == free_block){
284                     free_block = free_block->next;
285                     free(tmp);
286                 }else{
287                     FBT *t = free_block;
288                     while(t->next != tmp){
289                         t = t->next;
290                     }
291                     t->next = tmp->next;
292                     free(tmp);
293                 }
294             }
295             else{
296                 tmp->size = shengyu;
297                 tmp->start_addr = tmp->start_addr + request;
298             }
299             return ;
300         }
301         tmp = tmp->next;
302     }
303 }
304 int allocate_mem(AB *ab){
305     FBT *fbt,*pre;
306     int request_size=ab->size;
307     fbt = pre = free_block;
308     int f = find_free_mem(request_size);
309     if(f == -1){
310         //不够分配
311         printf("Free mem is not enough,Allocate fail!\n");
312         return -1;
313     }else{
314         if(f == 0){
315             memory_compact();
316         }
317         do_allocate_mem(ab);
318     }
319     rearrange(ma_algorithm);
320     return 1;
321 } 
322 int new_process(){
323     AB *ab;
324     int size;
325     int ret;
326     ab = (AB*)malloc(sizeof(AB));
327     if(!ab) exit(-5);
328 
329     ab->next=NULL;
330     pid++;
331     sprintf(ab->process_name,"PROCESS-%02d",pid);
332     ab->pid = pid;
333     printf("Memory for %s:",ab->process_name);
334     scanf("%d",&size);
335     if(size>0) ab->size=size;
336     ret = allocate_mem(ab);        
337     if((ret == 1) && (allocated_block_head == NULL)){
338         allocated_block_head = ab;
339         return 1;
340     }else if(ret == 1){
341         ab->next = allocated_block_head;
342         allocated_block_head = ab;
343         return 2;
344     }else if(ret == -1){
345         printf("\e[0;31;1m Allocation fail \e[0m\n");
346         free(ab);
347         return -1;
348     }
349     return 3;
350 }
351 void rearrange_FF(){
352     if(free_block == NULL || free_block->next == NULL)
353         return;
354     FBT *t1,*t2,*head;
355     head = free_block;
356     for(t1 = head->next;t1;t1 = t1->next){
357         for(t2 = head;t2 != t1;t2=t2->next){
358             if(t2->start_addr > t2->next->start_addr){
359                 int tmp = t2->start_addr;
360                 t2->start_addr = t2->next->start_addr;
361                 t2->next->start_addr = tmp;
362 
363                 tmp = t2->size;
364                 t2->size = t2->next->size;
365                 t2->next->size = tmp;
366             }
367         }
368     }
369 }
370 void rearrange_BF(){
371     if(free_block == NULL || free_block->next == NULL)
372         return;
373     FBT *t1,*t2,*head;
374     head = free_block;
375     for(t1 = head->next;t1;t1 = t1->next){
376         for(t2 = head;t2 != t1;t2=t2->next){
377             if(t2->size > t2->next->size){
378                 int tmp = t2->start_addr;
379                 t2->start_addr = t2->next->start_addr;
380                 t2->next->start_addr = tmp;
381 
382                 tmp = t2->size;
383                 t2->size = t2->next->size;
384                 t2->next->size = tmp;
385             }
386         }
387     }
388 }
389 void rearrange_WF(){
390     if(free_block == NULL || free_block->next == NULL)
391         return;
392     FBT *t1,*t2,*head;
393     head = free_block;
394     for(t1 = head->next;t1;t1 = t1->next){
395         for(t2 = head;t2 != t1;t2=t2->next){
396             if(t2->size < t2->next->size){
397                 int tmp = t2->start_addr;
398                 t2->start_addr = t2->next->start_addr;
399                 t2->next->start_addr = tmp;
400 
401                 tmp = t2->size;
402                 t2->size = t2->next->size;
403                 t2->next->size = tmp;
404             }
405         }
406     }
407 }
408 void rearrange(int algorithm){
409     switch(algorithm){
410         case MA_FF:rearrange_FF();break;
411         case MA_BF:rearrange_BF();break;
412         case MA_WF:rearrange_WF();break;
413     }
414 }
415 void set_algorithm(){
416     int algorithm;
417     printf("\t1 - First Fit\n");
418     printf("\t2 - Best Fit\n");
419     printf("\t3 - Worst Fit\n");
420     scanf("%d",&algorithm);
421     if(algorithm>=1 && algorithm<=3)
422         ma_algorithm = algorithm;
423     rearrange(ma_algorithm);
424 }
View Code
1 //mem.h
2 #define PROCESS_NAME_LEN 32 
3 #define MIN_SLICE 10         
4 #define DEFAULT_MEM_SIZE 1024    
5 #define DEFAULT_MEM_START 0        
6 
7 #define MA_FF 1
8 #define MA_BF 2
9 #define MA_WF 3
View Code

参考文献:

https://blog.csdn.net/baidu_35085676/article/details/78502503

https://cloud.tencent.com/developer/article/1585693

posted @ 2020-05-15 15:29  DAY--BY--DAY  阅读(1257)  评论(0编辑  收藏  举报