操作系統第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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM