昆明理工大学信息工程与自动化学院学生实验报告
( 2013 —2014 学年第 一 学期 )
课程名称:操作系统 开课实验室:信自楼444 2013年 11月28 日 年级、专业、班 物联网2011级 学号 实验项目名称 教师评 该同学是否了解实验内容与要求:A.了解□ 设计思想或流程图是否正确: A.正确□ A.强 □ B.基本了解□ C.不了解□ B.基本正确□ C.较差 □ B.中等 □ C.差 □ B.基本达到□ C.未达到□ B.基本规范□ C.不规范□ B.一般 □ C.没有 □ B.一般 □ C.没有 □ 固定分区存储管理 姓名 成绩 指导教师 语 该同学的实验能力: 该同学的实验是否达到要求: A.达到□ 实验报告是否规范: A.规范□ A.详细□ 是否有运行结果与分析: 是否有总结与体会: A.详细□ 教师签名: 年 月 日 注:报告内容按下列的要求进行。 一、 实验目的
通过编写固定分区存储管理的模拟程序,加深对操作系统存储管理功能中的固定分区管理方式、主存分配表等相应知识的理解。
通过编写和调试存储管理的模拟程序以加深对存储管理方案的理解,熟悉可变分区存储管理的内存分配和回收。 二、 实验题目
1. 设计一个固定分区分配的存储管理方案。并模拟实现分区的分配和回收过程。 2. 必须建立分区表,记录空闲区与占用区的状况。 3. 流程图按选定的算法自己完成。
-1-
三、 算法设计的思想或流程图
本系统将内存用户空间划分为五个大小不固定的分区,其分区大小由用户输入决定。在每个分区只装入一道作业,这样把用户空间划分为几个分区,便允许几道作业并发运行。当有一个空闲分区时,便可以从外存的后备队列中选择一个适当大小的作业装入该分区,当该作业结束时又可以从后备作业队列中找出另一作业调入该分区。
每个内存空间是一个Node型的对象。Node类有一个三个参数的构造函数。分别为:分区号、起始地址、大小。然后就是一些属性的get、set方法和一个打印其属性的函数。四个数据域分别为:属性m_No用来表示该内存空间的序号。属性m_Addr用来表示内存分区的起始地址。属性m_Size用来表示内存空间的大小。属性m_State表示内存空间的是否已分配的状态标志。若该内存空间已分配,m_TaskNo表示占有该内存空间的任务序号。否则没有实际意义。
在用户申请任务的内存空间时,提示用户输入任务号和其需要的内存空间大小。 流程图 主程序:
-2-
Y Swt==1? N Y Swt==2? N
Y yesorno!=’n’&& yesorno!=’N’ 提示用户是否继续操作(Y/N),将用户输入存放在变量yesorno中 default:抛出异常 执行分配给任务的内存空间分释放操作 进行任务的内存空间分配操作 swt!=1 并且swt!=2? 提示用户输入他的选择:1、申请内存空间 2、释放内存空间。 将用户输入存放入swt变量 让用户手工输入每个分区大小,来初始化内存空间 开始 创建MManage对象,内存空间长度为5. N
结束 -3-
分配内存空间算法: Y Y Temp1 -5- 将内存空间No置为占有,并将作业分配给它 申请失败 打印出内存空间信息 结束 开始 提示用户输入作业名 初值为0的变量i,是否小于节点队列大小 第i个内存占有并且其作业号等于输入的作业号 保存内存空间号到No 四、算法设计的实现 1、类设计 本程序设计了两个比较简单的类:Node类和MManage类。Node类主要是存放每个固定分区的一些信息。而MManage类则主要是对Node类的容器List 类设计的数据成员和接口如下: Node.h #ifndef NODE_H #define NODE_H class Node { public: No==-1? 将内存空间No置为空闲 释放失败 打印出内存空间信息 结束 Node(int No, int Addr, int Size); -6- int getSize() const { return m_Size; } bool getState() const { return m_State; } int getTaskNo() const { return m_TaskNo; } void setState(bool State); void setTaskNo(int TaskNo); void print(); private: int m_No; int m_Addr; int m_Size; bool m_State; int m_TaskNo; }; #endif //NODE_H -7- MManage.h #ifndef MMANAGE_H #define MMANAGE_H #include class Node; class MManage { public: //MManage(); MManage(int MLength); MManage(std::vector private: std::vector -8- }; #endif//MMANAGE_H 类接口实现和main函数的实现: Node.cpp #include #include \"Node.h\" Node::Node(int No, int Addr, int Size) { } void Node::setTaskNo(int TaskNo) { } -9- :m_No(No),m_Addr(Addr),m_Size(Size) m_State = true; m_TaskNo = 0; m_TaskNo = TaskNo; void Node::setState(bool State) { m_State = State; } void Node::print() { std::cout<<\"| \"< std::cout<<\"Idle ||\"< std::cout<<\"Occupy || \"< MManage.cpp #include #include \"MManag.h\" #include \"Node.h\" #define MAXSIZE 100 -10- //class Node; /*MManage::MManage() { } */ MManage::MManage(int MNo) { int sum; std::cout << \"Please input the number of memory:\"; std::cin >> sum; std::cout << std::endl; MManage(sum); int size; int addr = 0; char yesOrNo = 'n'; while ( yesOrNo != 'y' && yesOrNo != 'Y') { m_Nodes.clear(); std::cout << \"Start to init the memory table\" << std::endl; for (int i=0; i -11- } std::cout << \"Please input the size of \" << i+1 << \"th memory:\"; std::cin >> size; }while(size >= MAXSIZE); Node node(i+1, addr, size); m_Nodes.push_back(node); addr+=size; } } print(); std::cout << \"Is this correct?\" << std::endl; std::cin >> yesOrNo; MManage::MManage(std::vector void MManage::MAlloc() { m_Nodes.assign(Nodes.begin(), Nodes.end()); int taskNo, size; int No = -1; int temp1 = MAXSIZE; -12- int temp2 = MAXSIZE; bool flag; do{ flag=false; std::cout << \"Please input the task No. and size\" << std::endl; std::cin >> taskNo >> size; for(unsigned i=0; i if(size > MAXSIZE) { } std::cout<<\"The size is too big,please change it\"< for(unsigned i=0; i -13- } } { } temp2 = m_Nodes[i].getSize() - size; if(temp2 } if(No==-1) { } else { } std::cout << \"Allocation success.\" << std::endl; m_Nodes[No].setState(false); m_Nodes[No].setTaskNo(taskNo); std::cout << \"Allocation fail.\" << std::endl; void MManage::MFree() { int taskNo,No=-1; -14- } std::cout << \"Please input the task No.\" << std::endl; std::cin >> taskNo; for(unsigned i=0; i No = i; if(No==-1) { } else { } std::cout << \"Free success.\" << std::endl; m_Nodes[No].setState(true); m_Nodes[No].setTaskNo(0); std::cout << \"Free fail(Can not find the task).\" << std::endl; void MManage::print() -15- { std::cout << \"The the memory table:\" << std::endl; std::cout << \"| No |\" << \"| Addr |\" << \"| Size |\" << \"| State |\" << \"| TaskNo |\"<< std::endl; for (unsigned i=0; i } Main.cpp #include #include \"MManag.h\" #include \"Node.h\" #define SIZE 5 //分配区的个数 void testNode() { int size = 10; Node node1(1,0,size); node1.print(); Node node2(2,size,size); node2.setState(false); node2.setTaskNo(1); -16- } node2.print(); //MManage m1(); //m1.print(); MManage m2(2); m2.print(); int main() { MManage m(SIZE); char yesOrNo = 'y'; int swt = 0; while(yesOrNo != 'n' && yesOrNo != 'N') { while(swt != 1 && swt != 2) { system(\"cls\"); std::cout<<\"==========================\"< -17- } } } std::cout<<\"error iput,please put(1、2)\"< case 1: m.MAlloc(); break; case 2: m.MFree(); break; default: } m.print(); std::cout<<\"Do you like to continue?\"< { printf(\"exception ouccer\\n\"); return 1; } 四、 运行结果与分析 手工输入每个分区的大小来初始化分区表: -18- 分析:在手工输入每个内存空间的大小后,立即调用打印的函数将内存空间的情况打印出来。让用户确定自己输入是否正确。 分配成功: 分析:申请内存空间。首先得输入作业号与作业大小。在程序中是通过计算出最合适的内 -19- 空间(内存空间与作业大小之差最小)分配给当前作业。 如图,在作业,大小为4.在图中可以看出使用最佳适应算法,内存空间2与之最为合适.故将内存空间2分配给作业2.在内存空间的分配图也可以看得出来内存空间2被作业2占用。 分配失败: 分析:由于申请的作业3其大小超过了每一个内存空间的大小。故分配失败。 内存释放: -20- 分析:内存空间释放,先输入要释放的内存空间对应的任务号。然后通过查找出对应的内存空间,将其信息修改为空闲,作业号改为0.说明该内存空间被释放。 五、 总结体会 通过此次试验加深了对操作系统存储管理功能中的固定分区管理方式、主存分配表等相应知识的理解。对操作系统怎样实现存储管理有了初步的认识。 固定分区的优势是实现简单,只需要极少的操作系统开销。它也有很多的缺点,例如:有内部碎片,对内存的使用不充分、活动进程的最大数目是固定的等。 -21- 因篇幅问题不能全部显示,请点此查看更多更全内容