




版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、操作系统课程设计报告姓 名: 学 号: 班 级: 院 系: 日 期: 指导教师: 实验一:可变分区存储管理一、实验要求 设计合理的数据结构来描述存储空间:对于未分配出去的部分,可以用空闲分区队列来描述,对于已经分配出去的部分,由装入内存的作业占据,可以将作业组织成链表或数组。 实现分区存储管理的内存分配功能,要求选择至少两种适应算法(如首次适应算法,最佳适应算法,最后适应算法,最坏适应算法)。 实现分区存储管理的内存回收算法:要求能够正确处理回收分区与空闲分区的四种邻接关系。 当碎片产生时,能够进行碎片的拼接。二、设计目的在掌握了计算机可变分区存储管理方式的原理的基础上,利用c语言在windo
2、ws操作系统下模拟实现操作系统的可变分区存储管理的功能,以便加深对可变分区存储管理原理的理解,提高根据已有原理通过编程解决操作系统实际问题的能力,另一方面提高根据已有原理通过编程解决实际问题的能力,为进行系统软件开发和针对实际问题提出高效的软件解决方案打下基础。三、各功能模块分析实现需要设计合理的数据结构来描述存储空间,包括:被程序占用的存储空间、空闲的存储空间、多个程序的组织。通常用链表把这些同种类型的存储空间连接起来,使用结构体来描述每个存储空间的属性信息。根据可变分区存储管理的基本原理,程序的实现主要包括以下几个部分:1内存的初始化:包括确定内存的起始地址、内存的大小等。2要进入内存的程
3、序链表的产生:多个要进入内存运行的程序的产生,包括程序编号、所占存储空间的大小。可以把这些内容以记录式文件的形式保存到磁盘上,也可以把他们存放在二维数组中。若保存在文件中,则可以多次使用,如保存在数组中只能使用一次。3为程序分配存储空间: 可以采用首次适应、最佳适应、最后适应算法来实现。主要是按照这三种算法的思想对空闲块进行排序,以便找出符合要求的那个空闲块。对空闲块的排序思路可以使用冒泡排序算法的思想。4记录和显示内存被程序占用的情况5记录和显示内存中空闲块的情况6回收存储空间:程序运行完毕后,要及时回收内存空间。四、主程序流程图创建分区头节点删除上次的结果文件键盘输入字符stepiniti
4、aliziation字符step为? step=1 step=2 put job into memory step=6move fragment together step=3step=4 finish job step=5 show current memory used by jobsshow current free liststep=7exit五丶主要实验代码void init()/初始化,设置物理内存中用户区的大小,选取适应算法fl = null;/将各值复位al = null;jl = null;usermemory = 0;fitalgorithm = 0;count = 0;p
5、rintf(n请设置用户区的大小(整型):);cin usermemory;setfitalgorithm();fnode * tmp = (fnode *)malloc(sizeof(fnode);tmp-startaddress = 0;tmp-size = usermemory;/初始化时,将整个用户内存划分到一个分区里tmp-last = null;tmp-next = null;fl = tmp;void setfitalgorithm()/设置适应算法fitalgorithm = 0;while(fitalgorithm 4 | fitalgorithm fitalgorithm;
6、dofitalgorithm();void dofitalgorithm()/执行适应算法fnode * t = (fnode *)malloc(sizeof(fnode);int tmpstartaddress = 0;int tmpsize = 0;for (fnode * i = fl; i != null; i = i-next)t = i;for (fnode * j = i-next; j != null; j = j-next)switch(fitalgorithm)case 1:if (j-size size)/最佳适应算法,找到链表中分区大小最小的分区t = j;break;
7、case 2:if (j-size t-size)/最坏适应算法,找到链表中分区大小最大的分区t = j;break;case 3:if (j-startaddress startaddress)/首次适应算法,找到链表中分区起始地址最小的分区t = j;break;case 4:if (j-startaddress t-startaddress)/最后适应算法,找到链表中分区起始地址最大的分区t = j;break;tmpstartaddress = i-startaddress;/将剩余链中找到的分区交换到剩余链的最前端tmpsize = i-size;i-startaddress = t
8、-startaddress;i-size = t-size;t-startaddress = tmpstartaddress;t-size = tmpsize;void addjob()/添加作业int num = 0;int size = 0;printf(n);printf(请输入要加入的作业的编号(整型):);cin num;printf(请输入要加入的作业的大小(整型):);cin size;count+;jnode * job = (jnode *)malloc(sizeof(jnode);/初始化一个新作业结点job-id = count;job-num = num;job-siz
9、e = size;job-status = 0;job-last = null;job-next = null;if (jl = null)/将新作业加入作业链表中/若jl链为空,则直接将jl指向该结点jl = job; else/若jl不为空,则将该结点插入jl链的前端job-next = jl;jl-last = job;jl = job;dofitalgorithm();/在进行内存分配之前需执行适应算法if (allocatememory(job) = 0)/开始内存分配printf(n没有足够的内存空间分配給该作业!n); elseprintf(n该作业成功得到内存分配!n);int
10、 allocatememory(jnode * tmp)/内存分配int flag = 0;/用于标记新作业是否能被分配,0为不能for (fnode * i = fl; i != null; i = i-next)if (i-size = tmp-size)/找到一个符合要求的分区装入作业tmp-status = 1;/更改作业状态为已装入内存anode * t = (anode *)malloc(sizeof(anode);/初始化新加入的已分配分区结点t-jid = tmp-id;t-size = tmp-size;t-startaddress = i-startaddress;t-la
11、st = null;t-next = null;if (al = null)/将已分配的分区接入已分配分区链表中/若al链为空,则直接将al指向该结点al = t; else/若al不为空,则将该结点插入al链的前端t-next = al;al-last = t;al = t;if (i-size tmp-size)/若该分区大小大于作业大小,则将剩余大小重新赋给该分区i-startaddress = i-startaddress + tmp-size;i-size = i-size - tmp-size; else/若该分区大小恰好等于作业大小,则从空闲分区链表中删除该分区if (i-las
12、t = null)fl = i-next; else if (i-next = null)i-last-next = null; elsei-last-next = i-next;i-next-last = i-last;delete i;flag = 1;break;return flag;void finishjob()/完成作业jnode * job = (jnode *)malloc(sizeof(jnode);int flag = 0;/用于标记该id是否存在,0为不存在int id = 0;printf(n请输入要完成的作业的id(整型):);cin id;for (jnode *
13、 i = jl; i != null; i = i-next)/找出该id的作业if (i-id = id)job = i;flag = 1;break;if (flag = 0)printf(n该id不存在!n); elseif (job-last = null)/将已完成的作业从作业链表中删除jl = job-next;/若该job为链表头结点,则jl链表直接指向其下一个结点 else if (job-next = null)job-last-next = null; elsejob-last-next = job-next;job-next-last = job-last;delete
14、job;deallocatememory(id);/开始内存回收printf(n该作业成功完成!n);void deallocatememory(int jid)/内存回收anode * a = (anode *)malloc(sizeof(anode);int startaddress;/待合并分区的起始地址int endaddress;for (anode * i = al; i != null; i = i-next)/找到该作业所占的已分配分区if (i-jid = jid)a = i;break;startaddress = a-startaddress;endaddress = s
15、tartaddress + a-size - 1;if (a-last = null)al = a-next; else if (a-next = null)a-last-next = null; elsea-last-next = a-next;a-next-last = a-last;delete a;mergememory(startaddress, endaddress);/传入待合并分区的起始地址void mergememory(int startaddress, int endaddress)/合并分区fnode * ls = null;fnode * ns = null;fnod
16、e * t = (fnode *)malloc(sizeof(fnode);t-startaddress = startaddress;t-size = endaddress - startaddress + 1;t-last = null;t-next = null;for (fnode * i = fl; i != null; i = i-next)if (endaddress + 1) = i-startaddress)/查找与其结束地址后相邻的空闲分区ns = i;if (i-startaddress + i-size) = startaddress)/查找与其起始地址前相邻的空闲分区
17、ls = i;if (ls = null) & (ns = null)/没有相邻的空闲分区可以合并,则单独作为一个分区插入空闲分区链表if (fl = null)fl = t;elset-next = fl;fl-last = t;fl = t;if (ls != null) & (ns = null)/有前一个分区可以与之合并ls-size = ls-size + t-size;if (ls = null) & (ns != null)/有后一个分区可以与之合并ns-startaddress = t-startaddress;ns-size = ns-size + t-size;if (ls
18、 != null) & (ns != null)/前后两个分区都与之合并if (ns-last = null)/若ns为头结点,则fl链表直接指向其下一个结点fl = ns-next; else if (ns-next = null)/若ns为尾结点,则直接将该结点删除ns-last-next = null; elsens-last-next = ns-next;ns-next-last = ns-last;ls-size = ls-size + t-size + ns-size;delete ns;void defragment()/碎片整理,进行碎片拼接int sum = 0;/记录已分配
19、空间的总大小for (anode * i = al; i -next != null; i = i-next)i-startaddress = i -next -size + i -next-startaddress;/更改已分配分区的起始地址,将这些分区的地址移到内存的低址部分sum = sum + i-size;if (fl != null)/fl不为空表示还存在空闲空间,否则不存在空闲空间fl-next = null;/将剩余的空闲分区合并为一个分区fl-startaddress = sum;fl-size = usermemory - sum;printf(n碎片拼接完成!n);voi
20、d reload()/重新装入作业链中未装入内存的作业for (jnode * i = jl; i != null; i = i-next)if (i-status = 0)dofitalgorithm();/在进行内存分配之前需执行适应算法if (allocatememory(i) = 0)/开始内存分配printf(n没有足够的内存空间分配給 %d号作业!n, i-id); elsei-status = 1;printf(n %d号作业成功得到内存分配!n, i-id);void showflist()/显示当前空闲分区链的信息printf(n);printf(#当前空闲分区链信息#n);
21、printf(#分区起始地址分区大小n);for (fnode * i = fl; i != null; i = i-next)printf(#%10d, i-startaddress);printf();printf(|%10d, i-size);printf(n);printf(#n);printf(n);void showalist()/显示当前已分配分区链的信息printf(n);printf(#当前已分配分区链信息#n);printf(#分区起始地址分区大小分区作业号n);for (anode * i = al; i != null; i = i-next)printf(#%10d,
22、 i-startaddress);printf();printf(|%10d, i-size);printf();printf(|%10d, i-jid);printf(n);printf(#n);printf(n);void showjlist()/显示当前作业链的信息printf(n);printf(#当前作业链信息#n);printf(#作业id作业编号作业大小作业状态n);for (jnode * i = jl; i != null; i = i-next)printf(#%10d, i-id);printf();printf(|%10d, i-num);printf();printf
23、(|%10d, i-size);printf();if (i-status = 0)printf(| 未装入内存); elseprintf(| 已装入内存);printf(n);printf(#n);printf(n);void mainpage()/主界面int i = 0;printf(n);printf(#主界面#n);printf(#1-初始化(设置物理内存中用户区的大小,选取适应算法)n);printf(#2-作业进入内存(内存分配)n);printf(#3-作业完成(内存回收)n);printf(#4-显示当前空闲分区链的信息n);printf(#5-显示当前已分配分区链的信息n)
24、;printf(#6-显示当前作业链的信息n);printf(#7-碎片整理(碎片拼接)n);printf(#8-重新装入未装入内存的作业n);printf(#9-显示所有链的信息n);printf(#10-设置适应算法n);printf(#0-退出n);printf(#n);int main(void)mainpage();return system(pause);六丶实验截图:进行初始化:选择最佳适应算法:添加3个作业:显示空闲分区:显示当前已分配分区链信息:显示当前作业链信息:完成作业1和2:显示当前空闲分区:进行拼接后显示分区:七丶实验小结通过本次课程设计,自己的编程能力有所提高,对操
25、作系统内存的分配,存储空间的回收,以及碎片的拼接都有了全新的认识。在这次操作系统的课程设计我使用了c语言编写系统软件,对os中可变分区存储管理有了更深刻的理解。通过验证,可以说是做出结果。但是过程中遇到很多困难,只能边做边查资料,问同学。也许是程序的某个边界的设计不合理。在教案中提供了双向链表的实现方法,但是感觉对于性能提升影响不大,但是对于编程复杂度提高较多,实际做下来感觉这个方法比较鸡肋。通过试验,对于c的语句有了比较多的了解,我们原来学的是c+,但是发现c的i/o比于c+的似乎更为简便一些。任何输入而正常结束。很遗憾的是因为时间问题,没有把这个模拟程序写成动画形式,还可以加几句代码后实现
26、动态的增加作业。总而言之,究其原因还是自己平时没学牢固。希望在以后的学习中可以学到更多知识。实验二:多级队列调度算法模拟实现1.设计要求 在熟练掌握计算机处理机调度原理的基础上,利用一种程序设计语言模拟实现多级反馈队列进程调度算法,一方面加深对原理的理解,另一方面提高学生通过编程根据已有原理解决实际问题的能力,为学生将来进行系统软件开发和针对实际问题提出高效的软件解决方案打下基础。 调度算法中采用至少4级队列,每级队列的时间片大小预先指定。 由于只是模拟实现,调度的对象进程实际上并不包括程序和数据,而仅仅包括一个pcb数据结构,用pcb来代表一个进程,调度算法调度的对象只包括进程的pcb.处理
27、机的切换通过将pcb在运行指针和就绪队列之间进行移动来实现。又因为进程的组成只有pcb,没有程序和数据,因而进程只有运行和就绪两种状态,没有等待状态。 为避免显示结果超过1屏,调度结果要求写入文件中以方便检验。2.基础知识 由于处理机是计算机系统中最宝贵和稀有的资源,因而处理机调度是操作系统进行资源管理的一个重要功能。现代操作系统广泛采用多道程序设计的技术来提高系统吞吐量,提高程序的并发度和资源利用率。特别是进程调度程序,由于其运行频率高,更加要求调度算法简单,高效,系统开销小,进程切换快,可以说,调度算法的好坏直接影响整个计算机系统的性能。 多级队列调度算法是一种动态优先数调度算法。对于普通
28、的优先调度算法,如何确定进程优先级以真实地反映进程运行的紧迫程度是一个难题,但在多级队列调度算法中,可以预先规定优先级一样可以获得好的性能。该算法实际上综合了两种调度算法:队列内部是fcfs,队列之间是优先调度。3.数据结构参考 最核心的数据结构就是进程的逻辑结构。 进程中必须包括的内容很多(参见教材pcb部分的定义),为了简化起见,可以略去一些与本模拟调度算法关系不大的一些信息。请同学们自行设计,要求能够实现本调度算法即可。4.主程序流程图初始化输入a ;a=2创建进程n执行进程aenter?ynya=2?n撤消进程ya=3?n阻塞进程y唤醒进程a=4?na=0?ny退出系统终止5.程序运行
29、截图:此系统的界面是在dos界面下输出的,所以以下的输出结果均是dos界面截图。初始化界面:创建进程:依次创建进程:a,b,c和所需时间。运行进程: 进程运行结束:6.实验关键代码:int main(void) priocreate(); processcreate(); multidispatch(); output(); return 0; void output() readyqueue *print = head; pcb *p; printf(进程名t优先级t轮数tcpu时间t需要时间t进程状态t计数器n); while(print) if(print -linkpcb != nul
30、l) p=print -linkpcb; while(p) printf(%st%dt%dt%dt%dtt%ctt%dn,p-name,p-prio,p-round,p-cputime,p-needtime,p-state,p-count); p = p-next; print = print-next; p = finish; while(p!=null) printf(%st%dt%dt%dt%dtt%ctt%dn,p-name,p-prio,p-round,p-cputime,p-needtime,p-state,p-count); p = p-next; p = run; while(
31、p!=null) printf(%st%dt%dt%dt%dtt%ctt%dn,p-name,p-prio,p-round,p-cputime,p-needtime,p-state,p-count); p = p-next; void insertfinish(pcb *in) pcb *fst; fst = finish; if(finish = null) in-next = finish; finish = in; else while(fst-next != null) fst = fst-next; in -next = fst -next; fst -next = in; void
32、 insertprio(readyqueue *in) readyqueue *fst,*nxt; fst = nxt = head; if(head = null) in-next = head; head = in; else if(in -prio = fst -prio) in-next = head; head = in; else while(fst-next != null) nxt = fst; fst = fst-next; if(fst -next = null) in -next = fst -next; fst -next = in; else nxt = in; in
33、 -next = fst; void priocreate() readyqueue *tmp; int i; printf(输入就绪队列的个数:n); scanf(%d,&readynum); printf(输入每个就绪队列的cpu时间片:n); for(i = 0;i round); tmp -prio = 50 - tmp-round; tmp -linkpcb = null; tmp -next = null; insertprio(tmp); void getfirst(readyqueue *queue) run = queue -linkpcb; if(queue -linkpc
34、b != null) run -state = r; queue -linkpcb = queue -linkpcb -next; run -next = null; void insertlast(pcb *in,readyqueue *queue) pcb *fst; fst = queue-linkpcb; if( queue-linkpcb = null) in-next = queue-linkpcb; queue-linkpcb = in; else while(fst-next != null) fst = fst-next; in -next = fst -next; fst
35、-next = in; void processcreate() pcb *tmp; int i; printf(输入进程的个数:n); scanf(%d,&num); printf(输入进程名字和进程所需时间:n); for(i = 0;i name); getchar(); scanf(%d,&(tmp-needtime); tmp -cputime = 0; tmp -state =w; tmp -prio = 50 - tmp-needtime; tmp -round = head -round; tmp -count = 0; insertlast(tmp,head); void r
36、oundrun(readyqueue *timechip) int flag = 1; getfirst(timechip); while(run != null) while(flag) run-count+; run-cputime+; run-needtime-; if(run-needtime = 0) run -state = f; insertfinish(run); flag = 0; else if(run-count = timechip -round) run-state = w; run-count = 0; insertlast(run,timechip); flag
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2025年虚拟现实设计师考试试题及答案
- 2025年心理健康教育与咨询专业知识考试试题及答案
- 2025年刑法学考试试题及答案分析
- 2025年物理学专业研究生入学考试题及答案
- 2025年数据分析师考试模拟题及答案
- 2025年社区服务管理师考试试卷及答案
- 2025年软件工程专业考试题及答案
- 2025年会计电算化考试真题及答案
- 2025年健康管理与健康教育课程考试试题及答案
- 2025年古典文学专业研究生入学考试试卷及答案
- (新版)供电可靠性理论考试题库大全-上(单选、多选题)
- C型钢检验报告
- AS9100D体系标准中文版
- 艾滋病、梅毒、乙肝试验室检测技术
- 学前教育学备课课件(共54张PPT)
- 空调安装安全协议书1
- WS T 510-2016病区医院感染管理规范
- 中南大学计算机体系结构题库
- 儿童身高预测与促进课件
- 中小学教育惩戒规则(试行)解读课件
- 年产3000吨新茶饮及抹茶智能精深产能加工项目可行性研究报告-甲乙丙资信
评论
0/150
提交评论