操作系统课程设计报告书.docx
- 文档编号:8586567
- 上传时间:2023-01-31
- 格式:DOCX
- 页数:58
- 大小:629.70KB
操作系统课程设计报告书.docx
《操作系统课程设计报告书.docx》由会员分享,可在线阅读,更多相关《操作系统课程设计报告书.docx(58页珍藏版)》请在冰豆网上搜索。
操作系统课程设计报告书
南通大学计算机学院
《操作系统课程设计》项目
报告书
设计题目系统模拟
专业班级网络工程121
学生姓名******
学号1213072019
指导教师丁红
日期2014.07.04
1.课程设计题目:
模拟系统
1.1课程设计目的
操作系统模拟算法:
主要结合操作系统原理给出了实现操作系统基本技术所设计的数据结构和算法实现流程,以及一些算法的实现示例。
内容主要有处理机管理、存储器管理。
学生利用学过的操作系统原理课程参考教程进行上机实验,实验环境没有限制,与具体的硬件环境无关,所完全的所有程序都应该在MicrosoftVisualC++6.0环境下实现。
1.2课程设计要求
●系统功能要求
1.要求在控制台能够显示所有程序的导航功能,初始界面需要有处理机管理、主存空间的分配和回收、虚拟存储器管理三个选项。
2.处理机管理选项中需要包含先来先服务算法、时间片转轮算法、优先级调度算法中任意两种算法。
3.主存空间的分配和回收选项中需要包括首次适应算法和最佳适应算法。
4.虚拟存储器管理选项中需要包括先进先出算法和最少使用算法实现分页管理的缺页调度算法。
5.系统需要有必要的退出、循环机制。
●系统主要功能
处理机管理:
要求实现模拟CPU调度进程的动态过程。
主存空间的分配和回收:
要求实现主存对于进程的动态分配过程。
虚拟存储器管理:
要求实现缺页中断调度并运算出缺页中断率。
●报告要求
需要给出系统各个功能部分的详细描述,包括数据结构、流程图、部分代码分析、实验心得体会等。
2.课程设计报告内容
2.1系统主要模块介绍
本系统主要利用MicrosoftVisualC++6.0语言进行编写,主要模块有:
主界面操作模块、处理机调度模块、主存空间的分配和回收模块、虚拟存储器管理模块。
2.1.1系统模块结构图
图1
2.2主界面模块
2.2.1界面演示
图2主界面图
图3处理机管理界面
图4主存管理界面
图5虚存管理界面
2.2.2界面部分代码
intmain(){
cout<<"***********操作系统课程设计程序***********"< cout<<"***********by: 蔡鹏程************"< cout<<"***********学号: 1213072019***********"< intt;t=0; while(t! =4){ cout<<"***********主界面***********"< cout<<"1.处理机管理"< cout<<"2.主存空间的分配与回收"< cout<<"3.虚存管理"< cout<<"4.退出程序"< cout<<"选择你想要的操作: "< cout<<"******************************************"< loop: cin>>t; Sleep(100); switch(t) { case1: windows_cpu(t);break; case2: windows_M(t);break; case3: windows_VM(t);break; case4: break; default: { cout<<"输入错误请重新输入: "< } } } cout<<"**************谢谢使用,再见***************"< return0; } 2.2.3界面设计思路 本模块代码采用C++常用的switchcase语句进行选择编写,根据用户的选择恰当调用其他模块的函数,用常用函数库的清屏函数和sleep函数对界面进行美化。 2.3处理机管理模块 2.3.1按先来先服务的调度算法实现处理机调度 2.3.1.1算法描述 (1)假定系统中有3-5个进程,每个进程由一个进程控制块(PCB)来表示。 进程控制块的结构如图6所示。 进程控制块包括: 进程名、运行时间、到达时间、进程状态、链接指针组成。 (2)通过队首指针head,用来之处最先进入系统的进程,各就绪进程通过链接指针连在一起。 (3)处理机调度是选择队首指针指向的进程投入运行,在模拟过程中对进程不实际启动运行,只是执行估计运行时间减一,此操作用来模拟进程的一场运行,省去进程的现场保护和先恢复工作。 (4)有简单的显示和打印语句,显示运行的进程名、运行时间等属性。 图6PCB 2.3.1.2算法数据结构以及部分代码解析 1.进程控制块(PCB) typedefstructpcb//进程控制块 { charpname[N];//进程名 intruntime;//运行时间 intarrivetime;//到达时间 charstate;//进程状态就绪状态: R完成状态: C structpcb*next;//链接指针指向下一个进程 } 3.FCFS必要数据和函数清单 PCBhead_input;//就绪队列 PCBhead_run;//运行队列 staticcharR='r',C='c'; unsignedlongcurrent;//记录系统当前时间的变量 voidinputprocess();//建进程的函数 intreadydata();//就绪队列是否为空 intrunprocess();//运行进程 intreadyprocess();//检查队列并准备运行进程的函数 4.运行代码解析 p1=head_run.next; p2=&head_run; while(p1! =NULL) { p1->runtime--; current++; if(p1->runtime<=0) { printf("Timeis%4d;Process%send.\n",(current+500)/1000,p1->pname); p1->state=C; p2->next=p1->next; deletep1; p1=NULL; } 本段代码是运行进程时当运行队列队首不为空时进行进程运行,重复给队首进行占用时间片,当队首进程运行时间结束后,将程序从运行队列移出,转为下一个进程。 2.3.1.3算法效果演示 图7FCFS实现 2.3.2按时间片转轮法实现处理机调度 2.3.2.1算法描述以及算法数据结构 1.RR与FCFS代码比较 程序pcb和运行代码与上算法基本相同,代码不同处有2点: 1.FCFS就绪队列不空时,允许进入到运行队列的进程仅能有一个,但RR算法需要全部进入。 2.FCFS运行队列取进程运行后强行占有时间片直至结束,RR算法运行完单位时间片后加指针后移(轮转代码)。 2.装载代码解析 p3=head_input.next;p2=&head_input;//装载运行队列进程 while(p3! =NULL) { if(((unsignedlong)p3->arrivetime<=current)&&(p3->state==R))//满足条件 { printf("Timeis%4d;Process%sstart,\n",(current+500)/1000,p3->pname); p2->next=p3->next; p3->next=p1->next; p1->next=p3; p3=p2;if(! is_RR)gotoloop;//转移指令 } p2=p3; p3=p3->next; 2.3.2.2算法效果演示 图8RR算法实现 2.4主存空间的分配与回收模块 2.4.1首次适应法分配管理链式可变分区 2.4.1.1算法描述 当有进程要求分配主存时,依据首次适应算法从链头开始,沿链查找一个足矣容纳改进程的空闲区,若这个分区比较大,则一分为二,一部分分配给进程,另一部分作为空闲区仍留在链中的当前位置,修改它的上一个空闲区的向前指针值为再加上分配给进程的分区大小,下一个空闲区的向后指针值为再加上分配给进程的分区大小,使链保持完整。 若这个分区的大小正好等于进程大小,该空闲区全部分配给进程,并将该空闲区从链中摘除。 再在已分配表中找一个空目录,登记刚刚分配的内存始址、长度和进程号。 2.4.1.2算法数据结构以及部分代码解析 1.算法数据结构 structmemory { structmemory*former;//前向指针 intaddress;//地址 intnum;//作业号 intsize;//分配内存大小 intstate;//状态0表示空闲1表示已分配 structmemory*next;//后向指针 }; 2.必要数据和函数清单 typedefstructmemoryMEMORY; MEMORY*mem; constintsize_min=10;//内存允许的最小空闲块的大小 boolis_optimist;//判断是否是最佳适应算法 voidinit();//初始化内存块 voidexec();//执行相应算法 voidF_F(int);//依次初始化每个作业,并根据相应算法对作业分配内存 voidalloc(MEMORY*,MEMORY*);//分配内存算法(包括两种不同算法) voidfree(MEMORY*,int);//首次适应算法回收内存 voidfree_optimist(MEMORY*,int);//最佳适应算法回收内存 voidsort(MEMORY*);//对内存链进行排序 voidinsert(MEMORY*,MEMORY*);//按空间大小将作业顺序插入到内存链 voidprint(MEMORY*);//打印内存链 3.内存分配代码 用户在输入作业号后对将要运行的进程的属性进行输入,传输到alloc函数中进行分配判断 Ptr表示内存空间assign表示用户输入进程相关属性 voidalloc(MEMORY*ptr,MEMORY*assign) {//根据算法分配内存(is_optimist状态) if(ptr->next==NULL) {//内存没有作业运行 if(ptr->size>=assign->size) {//内存空间大于作业所需空间,为内存分配空间 ptr->size=ptr->size-assign->size; assign->state=1; ptr->next=assign; assign->former=ptr; cout<<"作业"<<(assign->num)<<"申请"<<(assign->size)<<""<<"k的内存空间"< } else { cout<<"没有足够的内存空间为作业"<<(assign->num)<<"分配"< deleteassign; } } else {//内存中如果已经分配了空间 MEMORY*previous,*current; previous=ptr;//previous为链表中的第一个元素 current=previous->next; while(current! =NULL) {//当前区间不为空(最后一个区间的next为空),即没有循环到最后 //如果当前内存空间大于作业所需空间并且内存没有被分配 //则结束循环,当前current位置即为要插入的位置 if(current->size>=assign->size&¤t->state==0) { break; } previous=current;//previous后移 current=current->next; } if(current==NULL) {//空闲链中没有为作业分配所需的空间,即释放的空闲区间小于要分配的作业空间 //不够用,则在所有作业后边另外再申请空闲区,如作业4 if(ptr->size>=assign->size) {//内存中还有足够没分配的空闲空间为此作业分配 //此时ptr指向内存上未分配空闲空间的起始地址 assign->address=640-(ptr->size); ptr->size=ptr->size-assign->size; assign->state=1; assign->former=previous; previous->next=assign; cout<<"作业"<<(assign->num)<<"申请"<<(assign->size)<<""<<"k的内存空间"< } else { cout<<"没有足够的内存空间为作业"<<(assign->num)<<"分配"< } } else {//释放的空闲链中有可为此作业分配的空间 if((current->size-assign->size)<=size_min) {//空闲链所具备的空间与作业所需空间大小差不多时 //直接把整个空闲块的空间分配给作业否则从空闲块中 current->num=assign->num;//划出与作业等同的空间 current->state=1; deleteassign; cout<<"作业"<<(current->num)<<"申请"<<(current->size)<<""<<"k的内存间"< } else {//从空闲块中划分一块与作业大小等同的空间 current->size=current->size-assign->size; assign->state=1; assign->address=current->address+current->size; if(current->next==NULL) {//此要分配的空间是空闲链的最后一个元素 assign->former=current; current->next=assign; } else { assign->next=current->next; (current->next)->former=assign; assign->former=current; current->next=assign; } cout<<"作业"<<(assign->num)<<"申请"<<(assign->size)<<""<<"k的内存空间"< }} 2.4.1.3算法效果演示 1.申请内存 申请空间: 1——130KB2——60KB3——100KB 图9申请空间1 图10申请空间2 图11申请空间3 2.释放内存 释放内存: 释放1 图12释放1号作业 2.4.2最佳适应法分配管理链式可变分区 2.4.2.1算法描述 采用最佳适应算法实现内存的分配与回收的实现原理以及使用的数据结构和首次适应算法类似。 所不同的是,分配时,总是分配与进程大小最接近的一个分区。 为此,可将空闲区按照大小,从小到大排列。 2.4.2.2算法数据结构以及部分代码解析 1.最佳适应算法与首次适应算法的比较 最佳适应算法的数据结构和必要的函数清单已在上显示,最佳适应算法在作业申请内存时,需要对可变分区大小进行排序,进而选取内存块最小的分区进行分配,这样在回收时,就显的异常麻烦,而首次适应算法则是对分区地址的顺序存取,按照分区地址的大小排序来进行内存的分配和管理 2.分区大小排序代码 voidsort(MEMORY*ptr) {//排序函数 MEMORY*temp=newMEMORY; temp->next=0; temp->former=0; while(ptr->next) { if((ptr->next)->next==NULL) {//内存链中只有两个元素 MEMORY*p; p=ptr->next; ptr->next=NULL; insert(temp,p);//从小到大插入排序 } else {//内存链中有多个元素 MEMORY*p; p=ptr->next; p->former=ptr; ptr->next=p->next; (p->next)->former=ptr; insert(temp,p);//从小到大插入排序 } } //temp为已经排好的作业队列 ptr->next=temp->next; (temp->next)->former=ptr;deletetemp;} 2.4.2.3算法效果演示 1.申请内存 在内存空间如图12的情况下进行分配: 作业4——120K 图12 图13申请空间 2.释放内存 释放作业2和4 图14释放作业2 图15释放作业4 2.5虚存管理模块 2.5.1采用FIFO算法实现分页管理的缺页调度 2.5.1.1算法描述 采用先进先出算法时,用一个数组表示先进先出队列,数组中的各个元素表示进程在主存的页号,假定块数不变,当队列有空余块时,将进程页号装载进数组中;当队列满需要淘汰是,淘汰最先进入主存的一页 2.5.1.2算法数据结构以及部分代码解析 1.页号以及作业(进程) structpage{//页面 intjobnum;//页块中作业号 intstage;//等级 }; structjob{ intjobnum;//作业号 intchgnum;//交换的作业号 }; 2.必要数据和函数清单 page*table; job*user; boolis_LRU;//is_FIFOoris_LRU voidsetpage(pagetable[],intn);//页面初始化 voidupstage(pagetable[],intn);//更新等级 voidsetjob(jobuser[],intn);//user用户作业初始化 voidrun(pagetable[],jobuser[],intm,intn);//运行 voidprint(job[]);//打印函数 3.代码分析 以下代码为作业进入时是否淘汰的判断,与LRU不同的是,当命中时页块不需要刷新操作。 for(inti=0;i { for(intj=0;j { if(table[j].jobnum==user[i].jobnum)//当命中时退出 gotoloop2;//转入下一个作业 } //未命中 for(j=0;j { if(table[j].stage==-1)//等级为-1表示未分配 { table[j].jobnum=user[i].jobnum;//改名 upstage(table,n);//更新页表 table[j].stage=0;//将此块等级改为0,最新 user[i].chgnum=0;//0表示由新装入 gotoloop2;//转入下一个作业 } }//无分配块且未命中 for(j=0;j { if(table[j].stage==n-1) { user[i].chgnum=table[j].jobnum;//淘汰页表 table[j].jobnum=user[i].jobnum;//更换页表 upstage(table,n);//更新等级 table[j].stage=0;//更改等级 gotoloop2;//转入下一个作业 } }//forj2 loop2: ; 2.5.1.3算法效果演示 注: 例题采用《操作系统教程第4版》第四章存储管理课后习题第1题3页框(LRU同) 图16FIFO 2.5.2采用LRU算法实现分页管理的缺页调度 2.5.2.1算法描述 采用LRU算法时,用一个数组表示先进先出队列,数组中的各个元素表示进程在主存的页号,假定块数不变,当队列有空余块时,将进程页号装载进数组中;当队列满需要淘汰是,淘汰最少使用的一页;当访问的页号与队列中的页号相等时,则进行队列页号等级刷新。 2.5.2.2算法数据结构以及部分代码解析 1.LRU与FIFO的比较 与FIFO不同的是,当命中时页块需要刷新命中块,并且更新其他页框。 2.代码分析 以下代码为作业进入时是否淘汰的判断 for(inti=0;i { for(intj=0;j { if(table[j].jobnum==user[i].jobnum)//当命中时退出 { upstage(table,n);//更新等级 table[j].stage=0;//刷新命中页块等级 gotoloop1;//转入下一个作业 } }//未命中 for(j=0;j { if(table[j].stage==-1)//有未分配 { table[j].jobnum=user[i].jobnum;//改名 upstage(table,n);//更新页表 table[j].stage=0;//将此块等级改为0,最新 user[i].chgnum=0;//0表示新装入 gotoloop1;//转入下一个作业 } }//无分配块且未命中 { intmax=table[0].stage;intindex=0; for(j=1;j { if(max {max=tabl 如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。 copyright@ 2008-2022 冰点文档网站版权所有 经营许可证编号:鄂ICP备2022015515号-1