这里直接给出代码,如果不理解请参考左万历版《计算机操作系统教程》,先在给出四中模拟算法。
1. 设计目的
了解动态分区分配中使用的数据结构和分配算法,并进一步加深对动态分区存储管理方式及其实现过程的理解。
2. 设计内容
1)用C语言实现采用首次适应算法的动态分区分配过程alloc()和回收过程free()。其中,空闲分区通过空闲分区链表来管理,在进行内存分配时,系统优先使用空闲区低端的空间。
2)假设初始状态如下,可用的内存空间为640KB,并有下列的请求序列;
作业1申请130KB
作业2申请60KB
作业3申请100KB
作业2释放60KB
作业4申请200 KB
作业3释放100 KB
作业1释放130 KB
作业5申请140 KB
作业6申请60 KB
作业7申请50KB
作业6释放60 KB
请采用数组四种算法进行内存块的分配和回收,同时显示内存块分配和回收后空闲内存分区链的情况。
*操作系统:首次适应算法的动态分区分配方式模拟
#include<iostream> #include<cstdio> #include<map> #include<cstring> #include<algorithm> #include<vector> #include<queue> #include<cmath> using namespace std; struct ready_node{//就绪的进程 int id;//进程编号 int flag;//表是进程的状态,1:表示进入内存,0:表示从内存撤出 int size;//进程长度 }; struct free_node{//空闲区域表的结构体,首地址和长度 int id;//保存在该区域的进行号 int start;//首地址 int len;//长度 }; vector<free_node> free_list;//保存空闲区域表的内容,分别是区域首址和区域长度 vector<free_node> used_list;//保存已占用区域表的内容,分别是区域首址和区域长度 queue<ready_node> ready_list;//就绪的进程队列,主要保存第一次匹配为成功的进程 queue<ready_node> wait_list;//等待的进程队列 //函数定义 int cmp(free_node a,free_node b);//定义排序的比较方式 void Show();//显示空闲区域表和已占用表的信息 void Init();//初始化等待序列 void Alloc(ready_node node);//动态分区分配函数 void Free(ready_node node);//回收过程函数 void Oper_FIRO();//操作函数 void Print();//显示最后控制台的空想区域表的状态,输入文件中 int main() { //重定向输入输出,对文件进行操作 freopen("input.txt","r",stdin); freopen("output8.txt","w",stdout); Init();//一定先进行初始化 Oper_FIRO(); //Print(); return 0; } int cmp(free_node a,free_node b){//定义排序的比较方式 return a.start<b.start;//按开始地址从小到大排序 } void Show(){//显示空闲区域表和已占用表的信息 sort(free_list.begin(),free_list.end(),cmp);//操作之前首先按首地址从小到大排序 printf("-----------------------\n"); printf("| 空闲链表的使用情况: |\n"); printf("-----------------------\n"); printf("---------------\n"); printf("| 首址 | 长度 |\n"); printf("---------------\n"); for(int i=0;i<free_list.size();i++){ printf("| %3d | %3d |\n",free_list[i].start,free_list[i].len); printf("---------------\n"); } printf("-------------------------\n"); printf("| 已占用链表的使用情况: |\n"); printf("-------------------------\n"); printf("----------------------------\n"); printf("|运行进程 | 首址 | 长度|\n"); printf("----------------------------\n"); for(int i=0;i<used_list.size();i++){ printf("| %3d | %3d | %3d |\n",used_list[i].id,used_list[i].start,used_list[i].len); printf("----------------------------\n"); } } void Init(){//初始化等待序列 free_node fnod; fnod.start=0; fnod.len=640;//初始化空闲表 free_list.push_back(fnod); ready_node node; while(scanf("%d%d%d",&node.id,&node.flag,&node.size)!=EOF){ wait_list.push(node); //cout<<node.size<<endl; } } void Alloc(ready_node node){//动态分区分配函数 sort(free_list.begin(),free_list.end(),cmp);//操作之前首先按首地址从小到大排序 //cout<<free_list.size()<<endl; free_node fnod; int ok=0;//表示是否匹配成功 vector<free_node>::iterator it;//定义迭代器 for(it=free_list.begin();it!=free_list.end();++it){ //cout<<(*it).start<<endl; if(((*it).len) >= node.size){ //记录已占用空间 fnod.len=node.size; fnod.start=(*it).start; fnod.id=node.id; used_list.push_back(fnod);//放入已占用区域表 (*it).start+=node.size; (*it).len-=node.size;//修改空闲区域表的信息 if((*it).len==0){//剩余空闲长度为0,移除这个空闲区域 free_list.erase(it); } ok=1;//已找到匹配 break; } } if(ok==0){//证明当前进程没有匹配成功,则放入就绪队列 ready_list.push(node); } printf("进程%d申请进入内存,内存占用大小为%dkb:\n",node.id,node.size); Show(); } void Free(ready_node node){//回收过程函数 //释放内存的过程中,进程正常都会在内存中出现,这里就假设释放的进程全部合法 free_node fnod; vector<free_node>::iterator it;//定义迭代器 for(it=used_list.begin();it!=used_list.end();++it){ if(((*it).id) == node.id){//找到撤销进程 //回收空闲空间,并放入空闲区域白哦,此时不用记录进程号,因为好没有进程占有空间 fnod.start=(*it).start; fnod.len=node.size; free_list.push_back(fnod);//放入空闲区域表 (*it).len-=node.size;//修改占用区域表的信息 if((*it).len==0){//撤销内存后,剩余的占有空间为0,移除这个空闲区域 used_list.erase(it); } break; } } printf("进程%d申请撤销,收回内存大小为%dkb:\n",node.id,node.size); Show(); } void Oper_FIRO(){//操作函数 ready_node node; while(!ready_list.empty()){//首先操作第一次未匹配的进程,此队列中只有进入内存的进程, //只组要调用分配函数Alloc()即可,不用调用回收函数Free() node=ready_list.front();//取出队首元素 ready_list.pop();//出队 Alloc(node); } while(!wait_list.empty()){//操作等待数列,有分配和回收两个过程 node=wait_list.front(); wait_list.pop(); if(node.flag==1){//申请进入内存的进程 Alloc(node); } else{//要撤出内存的进程 Free(node); } } } void Print(){//显示最后控制台的空想区域表的状态,输入文件中 //cout<<free_list.size()<<endl; sort(free_list.begin(),free_list.end(),cmp);//操作之前首先按首地址从小到大排序 for(int i=0;i<free_list.size();i++){ printf("%d %d\n",free_list[i].start,free_list[i].len); } }
*操作系统:循环首次适应算法的动态分区分配方式模拟
#include<iostream> #include<cstdio> #include<map> #include<cstring> #include<algorithm> #include<vector> #include<queue> #include<cmath> using namespace std; struct ready_node{//就绪的进程 int id;//进程编号 int flag;//表是进程的状态,1:表示进入内存,0:表示从内存撤出 int size;//进程长度 }; struct free_node{//空闲区域表的结构体,首地址和长度 int id;//保存在该区域的进行号 int start;//首地址 int len;//长度 }; vector<free_node> free_list;//保存空闲区域表的内容,分别是区域首址和区域长度 vector<free_node> used_list;//保存已占用区域表的内容,分别是区域首址和区域长度 queue<ready_node> ready_list;//就绪的进程队列,主要保存第一次匹配为成功的进程 queue<ready_node> wait_list;//等待的进程队列 size_t k=0;//循环指针;g int cmp(free_node a,free_node b){//定义排序的比较方式 return a.start<b.start;//按开始地址从小到大排序 } void Show(){//显示空闲区域表和已占用表的信息 sort(free_list.begin(),free_list.end(),cmp);//操作之前首先按首地址从小到大排序 printf("-----------------------\n"); printf("| 空闲链表的使用情况: |\n"); printf("-----------------------\n"); printf("---------------\n"); printf("| 首址 | 长度 |\n"); printf("---------------\n"); for(int i=0;i<free_list.size();i++){ printf("| %3d | %3d |\n",free_list[i].start,free_list[i].len); printf("---------------\n"); } printf("-------------------------\n"); printf("| 已占用链表的使用情况: |\n"); printf("-------------------------\n"); printf("----------------------------\n"); printf("|运行进程 | 首址 | 长度|\n"); printf("----------------------------\n"); for(int i=0;i<used_list.size();i++){ printf("| %3d | %3d | %3d |\n",used_list[i].id,used_list[i].start,used_list[i].len); printf("----------------------------\n"); } } void Init(){//初始化等待序列 free_node fnod; fnod.start=0; fnod.len=640;//初始化空闲表 free_list.push_back(fnod); ready_node node; while(scanf("%d%d%d",&node.id,&node.flag,&node.size)!=EOF){ wait_list.push(node); //cout<<node.size<<endl; } } void Alloc(ready_node node){//动态分区分配函数 sort(free_list.begin(),free_list.end(),cmp);//操作之前首先按首地址从小到大排序 //cout<<free_list.size()<<endl; free_node fnod; int ok=0;//表示是否匹配成功 for(int i=k;i<free_list.size();++i){ //cout<<(*it).start<<endl; if(free_list[i].len >= node.size){ //记录已占用空间 fnod.len=node.size; fnod.start=free_list[i].start; fnod.id=node.id; used_list.push_back(fnod);//放入已占用区域表 free_list[i].start+=node.size; free_list[i].len-=node.size;//修改空闲区域表的信息 /**此处应该是个bug,但是对与词组用例乜有影响,如果出现bug, *可以在输出函数里面进行处理,输出时跳过内容为-1的项即可。 */ if(free_list[i].len==0){//剩余空闲长度为0,全部赋值为-1.移除这个空闲区域 free_list[i].id=free_list[i].start=free_list[i].len=-1; } k=i+1; if(k>=free_list.size()) k=0; ok=1;//已找到匹配 break; } } if(ok==0){//证明当前进程没有匹配成功,则放入就绪队列 k=0; ready_list.push(node); } printf("进程%d申请进入内存,内存占用大小为%dkb:\n",node.id,node.size); Show(); } void Free(ready_node node){//回收过程函数 //释放内存的过程中,进程正常都会在内存中出现,这里就假设释放的进程全部合法 free_node fnod; vector<free_node>::iterator it;//定义迭代器 for(it=used_list.begin();it!=used_list.end();++it){ if(((*it).id) == node.id){//找到撤销进程 //回收空闲空间,并放入空闲区域白哦,此时不用记录进程号,因为好没有进程占有空间 fnod.start=(*it).start; fnod.len=node.size; free_list.push_back(fnod);//放入空闲区域表 (*it).len-=node.size;//修改占用区域表的信息 if((*it).len==0){//撤销内存后,剩余的占有空间为0,移除这个空闲区域 used_list.erase(it); } break; } } printf("进程%d申请撤销,收回内存大小为%dkb:\n",node.id,node.size); Show(); } void Oper(){//操作函数 ready_node node; while(!ready_list.empty()){//首先操作第一次未匹配的进程,此队列中只有进入内存的进程, //只组要调用分配函数Alloc()即可,不用调用回收函数Free() node=ready_list.front();//取出队首元素 ready_list.pop();//出队 Alloc(node); } while(!wait_list.empty()){//操作等待数列,有分配和回收两个过程 node=wait_list.front(); wait_list.pop(); if(node.flag==1){//申请进入内存的进程 Alloc(node); } else{//要撤出内存的进程 Free(node); } } } int main() { //重定向输入输出,对文件进行操作 freopen("input.txt","r",stdin); freopen("output9.txt","w",stdout); Init();//一定先进行初始化 Oper(); return 0; } *操作系统:最佳适应算法的动态分区分配方式模拟
#include<iostream> #include<cstdio> #include<map> #include<cstring> #include<algorithm> #include<vector> #include<queue> #include<cmath> using namespace std; struct ready_node{//就绪的进程 int id;//进程编号 int flag;//表是进程的状态,1:表示进入内存,0:表示从内存撤出 int size;//进程长度 }; struct free_node{//空闲区域表的结构体,首地址和长度 int id;//保存在该区域的进行号 int start;//首地址 int len;//长度 }; vector<free_node> free_list;//保存空闲区域表的内容,分别是区域首址和区域长度 vector<free_node> used_list;//保存已占用区域表的内容,分别是区域首址和区域长度 queue<ready_node> ready_list;//就绪的进程队列,主要保存第一次匹配为成功的进程 queue<ready_node> wait_list;//等待的进程队列 int cmp(free_node a,free_node b){//定义排序的比较方式 if(a.len<b.len) return 1;//按内存长度从小到大排序 if(a.len==b.len&&a.start<b.start) return 1;//如果长度相同,按照首地址从小到大排序 return 0; } void Show(){//显示空闲区域表和已占用表的信息 sort(free_list.begin(),free_list.end(),cmp);//操作之前首先按首地址从小到大排序 printf("空闲链表的使用情况: \n"); printf(" 首址 长度 \n"); for(int i=0;i<free_list.size();i++){ printf(" %3d %3d \n",free_list[i].start,free_list[i].len); } printf(" 已占用链表的使用情况: \n"); printf("运行进程 首址 长度\n"); for(int i=0;i<used_list.size();i++){ printf(" %3d %3d %3d \n",used_list[i].id,used_list[i].start,used_list[i].len); } } void Init(){//初始化等待序列 free_node fnod; fnod.start=0; fnod.len=640;//初始化空闲表 free_list.push_back(fnod); ready_node node; while(scanf("%d%d%d",&node.id,&node.flag,&node.size)!=EOF){ wait_list.push(node); //cout<<node.size<<endl; } } void Alloc(ready_node node){//动态分区分配函数 sort(free_list.begin(),free_list.end(),cmp);//操作之前首先按首地址从小到大排序 //cout<<free_list.size()<<endl; free_node fnod; int ok=0;//表示是否匹配成功 vector<free_node>::iterator it;//定义迭代器 for(it=free_list.begin();it!=free_list.end();++it){ //cout<<(*it).start<<endl; if(((*it).len) >= node.size){ //记录已占用空间 fnod.len=node.size; fnod.start=(*it).start; fnod.id=node.id; used_list.push_back(fnod);//放入已占用区域表 (*it).start+=node.size; (*it).len-=node.size;//修改空闲区域表的信息 if((*it).len==0){//剩余空闲长度为0,移除这个空闲区域 free_list.erase(it); } ok=1;//已找到匹配 break; } } if(ok==0){//证明当前进程没有匹配成功,则放入就绪队列 ready_list.push(node); } printf("进程%d申请进入内存,内存占用大小为%dkb:\n",node.id,node.size); Show(); } void Free(ready_node node){//回收过程函数 //释放内存的过程中,进程正常都会在内存中出现,这里就假设释放的进程全部合法 free_node fnod; vector<free_node>::iterator it;//定义迭代器 for(it=used_list.begin();it!=used_list.end();++it){ if(((*it).id) == node.id){//找到撤销进程 //回收空闲空间,并放入空闲区域白哦,此时不用记录进程号,因为好没有进程占有空间 fnod.start=(*it).start; fnod.len=node.size; free_list.push_back(fnod);//放入空闲区域表 (*it).len-=node.size;//修改占用区域表的信息 if((*it).len==0){//撤销内存后,剩余的占有空间为0,移除这个空闲区域 used_list.erase(it); } break; } } printf("进程%d申请撤销,收回内存大小为%dkb:\n",node.id,node.size); Show(); } void Oper(){//操作函数 ready_node node; while(!ready_list.empty()){//首先操作第一次未匹配的进程,此队列中只有进入内存的进程, //只组要调用分配函数Alloc()即可,不用调用回收函数Free() node=ready_list.front();//取出队首元素 ready_list.pop();//出队 Alloc(node); } while(!wait_list.empty()){//操作等待数列,有分配和回收两个过程 node=wait_list.front(); wait_list.pop(); if(node.flag==1){//申请进入内存的进程 Alloc(node); } else{//要撤出内存的进程 Free(node); } } } int main() { //重定向输入输出,对文件进行操作 freopen("input.txt","r",stdin); freopen("output10.txt","w",stdout); Init();//一定先进行初始化 Oper(); return 0; }
*操作系统:最坏适应算法的动态分区分配方式模拟
#include<iostream> #include<cstdio> #include<map> #include<cstring> #include<algorithm> #include<vector> #include<queue> #include<cmath> using namespace std; struct ready_node{//就绪的进程 int id;//进程编号 int flag;//表是进程的状态,1:表示进入内存,0:表示从内存撤出 int size;//进程长度 }; struct free_node{//空闲区域表的结构体,首地址和长度 int id;//保存在该区域的进行号 int start;//首地址 int len;//长度 }; vector<free_node> free_list;//保存空闲区域表的内容,分别是区域首址和区域长度 vector<free_node> used_list;//保存已占用区域表的内容,分别是区域首址和区域长度 queue<ready_node> ready_list;//就绪的进程队列,主要保存第一次匹配为成功的进程 queue<ready_node> wait_list;//等待的进程队列 int cmp(free_node a,free_node b){//定义排序的比较方式 if(a.len>b.len) return 1;//按内存长度从大到小排序 if(a.len==b.len&&a.start<b.start) return 1;//如果长度相同,按照首地址从小到大排序 return 0; } void Show(){//显示空闲区域表和已占用表的信息 sort(free_list.begin(),free_list.end(),cmp);//操作之前首先按首地址从小到大排序 printf("-----------------------\n"); printf("| 空闲链表的使用情况: |\n"); printf("-----------------------\n"); printf("---------------\n"); printf("| 首址 | 长度 |\n"); printf("---------------\n"); for(int i=0;i<free_list.size();i++){ printf("| %3d | %3d |\n",free_list[i].start,free_list[i].len); printf("---------------\n"); } printf("-------------------------\n"); printf("| 已占用链表的使用情况: |\n"); printf("-------------------------\n"); printf("----------------------------\n"); printf("|运行进程 | 首址 | 长度|\n"); printf("----------------------------\n"); for(int i=0;i<used_list.size();i++){ printf("| %3d | %3d | %3d |\n",used_list[i].id,used_list[i].start,used_list[i].len); printf("----------------------------\n"); } } void Init(){//初始化等待序列 free_node fnod; fnod.start=0; fnod.len=640;//初始化空闲表 free_list.push_back(fnod); ready_node node; while(scanf("%d%d%d",&node.id,&node.flag,&node.size)!=EOF){ wait_list.push(node); //cout<<node.size<<endl; } } void Alloc(ready_node node){//动态分区分配函数 sort(free_list.begin(),free_list.end(),cmp);//操作之前首先按首地址从小到大排序 //cout<<free_list.size()<<endl; free_node fnod; int ok=0;//表示是否匹配成功 vector<free_node>::iterator it;//定义迭代器 for(it=free_list.begin();it!=free_list.end();++it){ //cout<<(*it).start<<endl; if(((*it).len) >= node.size){ //记录已占用空间 fnod.len=node.size; fnod.start=(*it).start; fnod.id=node.id; used_list.push_back(fnod);//放入已占用区域表 (*it).start+=node.size; (*it).len-=node.size;//修改空闲区域表的信息 if((*it).len==0){//剩余空闲长度为0,移除这个空闲区域 free_list.erase(it); } ok=1;//已找到匹配 break; } } if(ok==0){//证明当前进程没有匹配成功,则放入就绪队列 ready_list.push(node); } printf("进程%d申请进入内存,内存占用大小为%dkb:\n",node.id,node.size); Show(); } void Free(ready_node node){//回收过程函数 //释放内存的过程中,进程正常都会在内存中出现,这里就假设释放的进程全部合法 free_node fnod; vector<free_node>::iterator it;//定义迭代器 for(it=used_list.begin();it!=used_list.end();++it){ if(((*it).id) == node.id){//找到撤销进程 //回收空闲空间,并放入空闲区域白哦,此时不用记录进程号,因为好没有进程占有空间 fnod.start=(*it).start; fnod.len=node.size; free_list.push_back(fnod);//放入空闲区域表 (*it).len-=node.size;//修改占用区域表的信息 if((*it).len==0){//撤销内存后,剩余的占有空间为0,移除这个空闲区域 used_list.erase(it); } break; } } printf("进程%d申请撤销,收回内存大小为%dkb:\n",node.id,node.size); Show(); } void Oper(){//操作函数 ready_node node; while(!ready_list.empty()){//首先操作第一次未匹配的进程,此队列中只有进入内存的进程, //只组要调用分配函数Alloc()即可,不用调用回收函数Free() node=ready_list.front();//取出队首元素 ready_list.pop();//出队 Alloc(node); } while(!wait_list.empty()){//操作等待数列,有分配和回收两个过程 node=wait_list.front(); wait_list.pop(); if(node.flag==1){//申请进入内存的进程 Alloc(node); } else{//要撤出内存的进程 Free(node); } } } int main() { //重定向输入输出,对文件进行操作 freopen("input.txt","r",stdin); freopen("output11.txt","w",stdout); Init();//一定先进行初始化 Oper(); return 0; }
附录:
input.txt输入文件格式:
1 1 130
2 1 60
3 1 100
2 0 60
4 1 200
3 0 100
1 0 130
5 1 140
6 1 60
7 1 50
6 0 60
时间: 2024-11-07 04:03:38