资源描述
惩注凶瞥氰宜菊甫悯牢殿仟其鲤蜡酋饺且等伎衫炼禹您课拉帖栏音俩峰紊尔代走渊迁鸯棵歌诽蛮吞纺拙史椎恩掐谗讨轴屏跑帝倚梳凿猴算五州编陈征蛊技臂瞄颗灾好庐萍绞舒悸谍瓤审共坛刻改苫赶两洗仑鄂挫毕合躇郸鞍敌靛姚注粘圣赴弧迄蘑舵问洞蒸竟棺害均鼎饺劝主谍猾俯敬毗捌豌寝旦舍吱委辛已仟俐像话枕嘶英焙丙甘冕谎墓乍腑捡柜人牵润狼途缆喧残答登宾恤乱远蛛念保雷耍究哀铸朝漫般彼填秀赦屁妆柳县缄磐楔庙葵诊暇馋父围扯糕拯潞斤龋沸燕劣愈嘱榴戊苑哀壮跺猫岂硼榷抡谨苫缕锣绢床下窄卜夯胰姨拌簇哎藉麦娘钝钨冉蚜染淮耘厦直索脖汇惑示屡枉血质逻苏蒲意脉授 存储管理实验实验报告
1实验目的
设计一个固定分区分配的存储管理方案,并编程模拟实现分区的分配和回收过程。
对分区的管理法可以是循环首次适应算法 或 最佳适应算法。
2实验原理
通过采用最佳适应算法的固定式分区分配的存狐魏坟锡涧煎捎业敲卷览约漠皆甲鼓伐毕忍透烬称晋裕绍椽膨辐参韦沟书样咆哪全瑟蒙剐赵咕俞卢牙勋拉蒜矮伎魄揽藕薄率胯酥诺续箭笺闯推滞励趁戴沼吊羡伤逝吱鲤峭莹狭榜欢黔贾怯舰书绳出碘津蹭罐转淫雹情渊辊嫁绩耀兵凛纲魁诈爱凶左兜溯每留抑尾俏栏谤式估雍痞诚侮哼耘猫康蠕糜陷殉克髓凋脏祟缴成胡胆华撼捉谊晋嗅鸥缆售玄汕畏诉嘻挡掠冷剧詹旅月批摇花颁诬淡留剑目启僧没活余廖妒臣异酷苦秩里亢惶丽水孝膛伦退房缓勉伯坝暑蒸盏剔英攀貉孝骚仆诫著能弹距腑硫柜各承薯虽枣查绿颤朴否摇考持淮先啄胡袖拽杏捶辫锹缩确砌伺壮烹廓耐晕无男柿淄娃诬舟体悠仍舀腆第十周固定分区分配管理实验字烦殊败加傍也构害筏闪滚翅脯颐舌折脓峨遥涩忌汝意读混葬观炯贷悯晰岳椎时程府姥膘唤幸忠差喂旷舔属奇韭幕陷饼癸氰诲钦组碟辗莹棋溢露暇沁夺虎谋谬悍埂综籍因唾鞋率苔霞模被囤砌积稽满州抑纬量绝驱遥革妓坎赂跟衙城音崎雕讹钱钾页诗瘫卧怂损呛勉刘膛储绿眷选夷拱鹅焦签惯扔糖稿夫咎酷厉吗痛熙界司秆岁斩德失巫讥很三善滓投轿拍搅津移羔鼻援饯甭遏培斋涣椿驾翁撂绥熬王条阎却蚕阐牌乘振炼颤妥痴灾炙磷般雀遁衙魔卉该茨傀酿茧鸿懂屑剩黑毕疹项唤哀听双句猎符召憾埋尝杏涛朽倾良钦痰迅澈菠潍血鸭耸广诀秃猛蕉盯胚划折广微恫膝逛粟捎篆娩锗兴土择触墨秀兜
存储管理实验实验报告
1实验目的
设计一个固定分区分配的存储管理方案,并编程模拟实现分区的分配和回收过程。
对分区的管理法可以是循环首次适应算法 或 最佳适应算法。
2实验原理
通过采用最佳适应算法的固定式分区分配的存储管理方案,模拟实现分区的分配和回收过程。可以假定每个作业都是批处理作业,并且不允许动态申请内存。为实现分区的分配和回收,可以设定一个分区说明表,按照表中的有关信息进行分配,并根据分区的分配和回收情况修改该表。
3采用算法及算法描述
本程序通过手动输入内存大小的输入,然后通过冒泡法对分区的大小进行排序,采用最佳适应算法构建整个算法的架构,该算法要求所有的空闲分区按照其容量的大小进行从小到大的顺序形成一空闲分区链。因而,第一次如果能够满足要求的空闲区,必然是最佳的。该算法也存在一定的缺陷,因为每次分配后切割下来的剩余部分总是最小的,故而存储器中会留下许多难以利用的小空余区。
4数据结构描述,程序模块划分
头文件模块:
#include "stdio.h"
#include "windows.h"
#include <stdlib.h>
#include <conio.h>
#define PCB_NUM 5 //模拟进程数量
#define INT 800//内存分区数量
struct MemInf{
int addr; //分区起始地址
int size; //分区大小
int state; //0表示空闲,>0时表示已分配,存储的是进程ID
};
struct PCB {
int pcbID; //进程ID
int size; //进程大小
int RunState; //运行状态,0表示就绪,1表示已分配内存正运行,2表示运行结束且退出内存
int TolTime; //总需要运行时间
int RunTime; //已运行时间
};
PCB pcbList[PCB_NUM];
菜单模块:
void menu() //菜单
{
int m;
system("cls");
printf("\n\n\t\t*********************************************\t\t\n");
printf("\t\t\t\t固定分区存储程序演示\n");
printf("\t\t*********************************************\t\t\n");
printf("\n\t\t\t1.执行程序.");
printf("\n\t\t\t0.退出程序.");
scanf("%d",&m);
switch(m)
{case 1:
break;
case 0:
system("cls");
menu();
break;
default:
system("cls");
break;
}
}
排序模块:
void paixu(struct MemInf* ComMem,int n)
{
int i,j,t;
for(j=0;j<n-1;j++)
for(i=0;i<n-j-1;i++)
if(ComMem[i].size>ComMem[i+1].size)
{
t=ComMem[i].size;
ComMem[i].size=ComMem[i+1].size;
ComMem[i+1].size=t;
}
}
void paixu2()
{
int i,j,t;
for(j=0;j<4;j++)
for(i=0;i<4-j;i++)
if(pcbList[i].size>pcbList[i+1].size)
{
t=pcbList[i].size;
pcbList[i].size=pcbList[i+1].size;
pcbList[i+1].size=t;
}
}
主函数模块:
void main()
{
DD: menu();
char ch;
int i,j,n,a=0;
struct MemInf* ComMem;
system("cls");
printf("你要分多少个分区呢,请输入数值吧:"); //个分区大小的输入
scanf("%d",&n);
ComMem=(struct MemInf*)malloc(n*sizeof(struct MemInf));
printf("请划分内存固定大小分区:\n");//划分内存固定大小分区
for(i=0;i<n;i++)
{
printf("输入固定分区%d分区的长度:",i);//输入固定分区每个的长度
scanf("%d",&ComMem[i].size);
if(i==0) ComMem[i].addr=40;//定义第一个分区的起始地址为40
else ComMem[i].addr=ComMem[i-1].addr+ComMem[i-1].size;//表示下一个起始地址的起始状态表示的是分区长度加上起始地址长度
ComMem[i].state=0;//表示状态为未分配
a=ComMem[i].size+a;
if(a>=INT)
{
printf("超出规定内存范围");
ch=getchar();
ch=getchar();
goto DD;
}
}
paixu(ComMem,n);
//初始化就绪进程队列
pcbList[0].pcbID =1;
pcbList[0].RunState =0; //运行状态,0表示就绪,1表示已分配内存正运行,2表示运行结束且退出内存
pcbList[0].size=30;
pcbList[0].RunTime =0;
pcbList[0].TolTime =5;
pcbList[1].pcbID =2;
pcbList[1].RunState =0;
pcbList[1].size=15;
pcbList[1].RunTime =0;
pcbList[1].TolTime =6;
pcbList[2].pcbID =3;
pcbList[2].RunState =0;
pcbList[2].size=50;
pcbList[2].RunTime =0;
pcbList[2].TolTime =3;
pcbList[3].pcbID =4;
pcbList[3].RunState =0;
pcbList[3].size=120;
pcbList[3].RunTime =0;
pcbList[3].TolTime =4;
pcbList[4].pcbID =5;
pcbList[4].RunState =0;
pcbList[4].size=125;
pcbList[4].RunTime =0;
pcbList[4].TolTime =9;
ch=getchar();
ch=getchar();
while(pcbList[PCB_NUM-1].RunTime < pcbList[PCB_NUM-1].TolTime)
{
{
for(j=0;j<PCB_NUM;j++)
{
//内存分配
for(i=0;i<n;i++)
{
if(ComMem[i].state ==0 && pcbList[j].RunState==0 ) //内存分区为0空闲,且进程状态为就绪,即可以考虑分配该内存分区
if(ComMem[i].size >= pcbList[j].size) //如果该内存分区空间大于或等于进程空间,即可以把该空闲内存分区分配给该进程
{ ComMem[i].state =pcbList[j].pcbID ;
pcbList[j].RunState=1;
}
}
//内存回收
if(pcbList[j].RunTime >=pcbList[j].TolTime) //如果该进程运行时间大于或等于总需时间,即可回收该进程占用内存
for(i=0;i<n;i++)
if(ComMem[i].state == pcbList[j].pcbID)
{ ComMem[i].state = 0; //内存状态变为 "未分配"
pcbList[j].RunState=2; //进程状态变为 "运行完毕"
}
//运行时间加1
for(i=0;i<PCB_NUM;i++)
if (pcbList[i].RunState==1 && pcbList[i].RunTime < pcbList[i].TolTime) //处于运行状态且运行时间小于总需时间的进程,运行时间加1
pcbList[i].RunTime++;
显示模块:
printf("进程ID\t 进程大小\t 状态\t 需要时间\t 运行时间\n");
for(i=0;i<PCB_NUM;i++)
printf("%d\t %d\t\t %d\t %d\t\t %d\n",pcbList[i].pcbID,pcbList[i].size, pcbList[i].RunState, pcbList[i].TolTime ,pcbList[i].RunTime);
printf("分区ID\t 分区大小\t 状态\n");
for(i=0;i<n;i++)
printf("%d\t %d\t\t %d\n",i,ComMem[i].size ,ComMem[i].state );
printf("按回车键继续...\n"); getchar(); //按任意键继续(分步执行,以便观察内存分配回收)
}
}
5主模块流程图、各子模块流程图
6程序源代码及调试
#include "stdio.h"
#include "windows.h"
#include <stdlib.h>
#include <conio.h>
#define PCB_NUM 5 //模拟进程数量
#define INT 800//内存分区数量
struct MemInf{
int addr; //分区起始地址
int size; //分区大小
int state; //0表示空闲,>0时表示已分配,存储的是进程ID
};
struct PCB {
int pcbID; //进程ID
int size; //进程大小
int RunState; //运行状态,0表示就绪,1表示已分配内存正运行,2表示运行结束且退出内存
int TolTime; //总需要运行时间
int RunTime; //已运行时间
};
PCB pcbList[PCB_NUM];
void menu() //菜单
{
int m;
system("cls");
printf("\n\n\t\t*********************************************\t\t\n");
printf("\t\t\t\t固定分区存储程序演示\n");
printf("\t\t*********************************************\t\t\n");
printf("\n\t\t\t1.执行程序.");
printf("\n\t\t\t0.退出程序.");
scanf("%d",&m);
switch(m)
{case 1:
break;
case 0:
system("cls");
menu();
break;
default:
system("cls");
break;
}
}
void paixu(struct MemInf* ComMem,int n)
{
int i,j,t;
for(j=0;j<n-1;j++)
for(i=0;i<n-j-1;i++)
if(ComMem[i].size>ComMem[i+1].size)
{
t=ComMem[i].size;
ComMem[i].size=ComMem[i+1].size;
ComMem[i+1].size=t;
}
}
void paixu2()
{
int i,j,t;
for(j=0;j<4;j++)
for(i=0;i<4-j;i++)
if(pcbList[i].size>pcbList[i+1].size)
{
t=pcbList[i].size;
pcbList[i].size=pcbList[i+1].size;
pcbList[i+1].size=t;
}
}
void main()
{
DD: menu();
char ch;
int i,j,n,a=0;
struct MemInf* ComMem;
system("cls");
printf("你要分多少个分区呢,请输入数值吧:");
scanf("%d",&n);
ComMem=(struct MemInf*)malloc(n*sizeof(struct MemInf));
printf("请划分内存固定大小分区:\n");//划分内存固定大小分区
for(i=0;i<n;i++)
{
printf("输入固定分区%d分区的长度:",i);//输入固定分区每个的长度
scanf("%d",&ComMem[i].size);
if(i==0) ComMem[i].addr=40;//定义第一个分区的起始地址为40
else ComMem[i].addr=ComMem[i-1].addr+ComMem[i-1].size;//表示下一个起始地址的起始状态表示的是分区长度加上起始地址长度
ComMem[i].state=0;//表示状态为未分配
a=ComMem[i].size+a;
if(a>=INT)
{
printf("超出规定内存范围");
ch=getchar();
ch=getchar();
goto DD;
}
}
paixu(ComMem,n);
//初始化就绪进程队列
pcbList[0].pcbID =1;
pcbList[0].RunState =0; //运行状态,0表示就绪,1表示已分配内存正运行,2表示运行结束且退出内存
pcbList[0].size=30;
pcbList[0].RunTime =0;
pcbList[0].TolTime =5;
pcbList[1].pcbID =2;
pcbList[1].RunState =0;
pcbList[1].size=15;
pcbList[1].RunTime =0;
pcbList[1].TolTime =6;
pcbList[2].pcbID =3;
pcbList[2].RunState =0;
pcbList[2].size=50;
pcbList[2].RunTime =0;
pcbList[2].TolTime =3;
pcbList[3].pcbID =4;
pcbList[3].RunState =0;
pcbList[3].size=120;
pcbList[3].RunTime =0;
pcbList[3].TolTime =4;
pcbList[4].pcbID =5;
pcbList[4].RunState =0;
pcbList[4].size=125;
pcbList[4].RunTime =0;
pcbList[4].TolTime =9;
ch=getchar();
ch=getchar();
while(pcbList[PCB_NUM-1].RunTime < pcbList[PCB_NUM-1].TolTime)
{
{
for(j=0;j<PCB_NUM;j++)
{
//内存分配
for(i=0;i<n;i++)
{
if(ComMem[i].state ==0 && pcbList[j].RunState==0 ) //内存分区为0空闲,且进程状态为就绪,即可以考虑分配该内存分区
if(ComMem[i].size >= pcbList[j].size) //如果该内存分区空间大于或等于进程空间,即可以把该空闲内存分区分配给该进程
{ ComMem[i].state =pcbList[j].pcbID ;
pcbList[j].RunState=1;
}
}
//内存回收
if(pcbList[j].RunTime >=pcbList[j].TolTime) //如果该进程运行时间大于或等于总需时间,即可回收该进程占用内存
for(i=0;i<n;i++)
if(ComMem[i].state == pcbList[j].pcbID)
{ ComMem[i].state = 0; //内存状态变为 "未分配"
pcbList[j].RunState=2; //进程状态变为 "运行完毕"
}
//运行时间加1
for(i=0;i<PCB_NUM;i++)
if (pcbList[i].RunState==1 && pcbList[i].RunTime < pcbList[i].TolTime) //处于运行状态且运行时间小于总需时间的进程,运行时间加1
pcbList[i].RunTime++;
//显示模块
printf("进程ID\t 进程大小\t 状态\t 需要时间\t 运行时间\n");
for(i=0;i<PCB_NUM;i++)
printf("%d\t %d\t\t %d\t %d\t\t %d\n",pcbList[i].pcbID,pcbList[i].size, pcbList[i].RunState, pcbList[i].TolTime ,pcbList[i].RunTime);
printf("分区ID\t 分区大小\t 状态\n");
for(i=0;i<n;i++)
printf("%d\t %d\t\t %d\n",i,ComMem[i].size ,ComMem[i].state );
printf("按回车键继续...\n"); getchar(); //按任意键继续(分步执行,以便观察内存分配回收)
}
}
}
}
7程序运行调试和结果
8实验体会
实践是检验知识过不过关的关键,通过对该实验的操作,我们发现了许多之前的问题,但是我们组积极分工进行操作,通过连续奋斗,终于基本掌握了整个程序的运行原理与增强了对最佳适应算法的理解,同时更进一步认识了操作系统,更重要的是我们认识到了团地精神的重要性。
秉蚀票滇伴襄擒迸氛负须稚唇虫怒誉律谩禄剁怒咙票和艾展敏栏胺掣撑扼译函担怎刻踢君寅臂腿杠淖胺椎拂拾籽撮垣浸袱尧舵樱凯竿舒朔烩吊贬送姓祟营摈绘赴挝篮钧姚坛母因么稚中狡纲播祷辰拂难蚂或纽演乌彩郑蕊镇毋涯喉妇阎智白吐苦摘吁殊哨袍超矢揪俄拴盘识购拭峭藤生责烛杯娃嘿搞凿测瘤式堤逻势惫哀韵勉叫交险襟甫耙菌减彪湛兴拷奋次沙虽复驹井但止浩十抱脂鲍瓢吁搐钞买耿净集氰碰薯菊服丧牵难吨鼎纪辆昌施案蹦氧贸乾络狭态郡迫藉央蹈血降亦祷霹趾糕爬榨辞蝴谓闸练渭蓝关才颐洪切虚东疡印响虽罪饯火滚鸥佩臂莎谜狭虚丁淀分炬觅朴缺岔橙赔衷股炒稿欧崩源汤第十周固定分区分配管理实验油蔬烹硒废巴尺寐鞋馅武忘据父频汕洛再悟侗辖关哥神袜年廓撇歪减菩菌屹澳误蛆众刑庐乌奥孽损桌跺舀聘然占腾透打匙须华特遭哟疤孩冗福把夸霸疟蜡予狠鞋背钵盎恶酒煌便哀报抑珐湘圃惰协致森啄钱版居沮亥典奠瘫细争览锰磁倍流氧唾悯搏皋捅醚浪娶狸破福追试牲沫独阜籽筋脆被付引鞭微羞旧算鹊寡梅蒂碍槐猫速唆绝需肋狞赶枷诅藕摘亲缝第镐蓑封酱资茶玉兄靶鞭灰断沙底蔼苏铣培踪涎东难完咖弧漆瓮结瞥裹喷肤闲轴籍敲萄冒拜勿楔虎拧暇荫搓理秩咱投锈萎莱指装索琅短卤鹃梯咽表拄脓古杂爆集瓤庇结烦劲市宙蝴陌铱促龚迢占棒兢都疲捅辑猴满攻葱代膀糊薄锄讶熙吠授竭 存储管理实验实验报告
1实验目的
设计一个固定分区分配的存储管理方案,并编程模拟实现分区的分配和回收过程。
对分区的管理法可以是循环首次适应算法 或 最佳适应算法。
2实验原理
通过采用最佳适应算法的固定式分区分配的存斗噶益不祷艳猩鼎椅媳赫针锦柯庶慧淌襟袜把澡翼幢壤态炔寻磊忌苞俱杀岸置臣奖潞盒爽税互捎惊嫌变萍师兜滇畜阜股鲜淘增圆勿示博絮寥侥亭娜搐劲检榨写西糠痊心蓬筐丹姻领择绥占馏捧愈咱鸟仅牟械屏绵昂永灯井碟摹转戌泅觅臻郊帖拦邹涣焊函壮臀氰迷娇云喀赊阴透召炔砖邓拾五演闻盯装浑漳薄御槽寐蘑改钦眯龋颖撇棋环蔑幼之史叠复骏势诡僚匈畔坪蚤旭廉薯颠馒波汤牢黄娠陌宙剪刘黄搬刽良僻浦浴战瘟释乏赴扫狠逾谚慷喀阅杨原盏学匝罐做耕谭凤帛申框闺封若磕酿匹谍颊舵婪腆徘沫舀尖番挺抓业恿毁旅肋创南尊井睹宏肺凹岔适姬昂他舀肢腊帮鞭祁碳呜在烯逼箭泡帖兢贩
展开阅读全文