电子科大-计算机-操作系统实验报告-2014级(共18页)_第1页
电子科大-计算机-操作系统实验报告-2014级(共18页)_第2页
电子科大-计算机-操作系统实验报告-2014级(共18页)_第3页
电子科大-计算机-操作系统实验报告-2014级(共18页)_第4页
电子科大-计算机-操作系统实验报告-2014级(共18页)_第5页
已阅读5页,还剩14页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、精选优质文档-倾情为你奉上电 子 科 技 大 学实 验 报 告学生姓名:郫县LBJ 学号:66 指导教师:温柔可爱的刘杰彦实验地点:主楼A2-413 实验时间:2017年4月22日上午1、 实验室名称:计算机学院主楼机房2、 实验项目名称:进程与资源管理实验分工:郫县LBJ 进程管理设计 郫县小胖子 资源管理设计 郫县威斯布鲁克 进程调度与时钟中断设计3、 实验学时:24、 实验原理: 此处的实验原理在指导书上非常丰富,因此不照搬过来,主要写出所要使用到知识点,具体实现过程中的原理分析见报告第八部分“实验步骤”处。(一) 总体设计系统总体架构如图1所示,最右边部分为进程与资源管理器,属于操作系

2、统内核的功能。要求能够设计与实现一个简单的进程与资源管理器,具有如下功能:完成进程创建、撤销和进程调度;完成多单元 (multi_unit)资源的管理;完成资源的申请和释放;完成错误检测和定时器中断功能。图1 系统总体结构(二) Test shell设计应具有的功能:1、从终端或者测试文件读取命令;2、将用户需求转换成调度内核函数(即调度进程和资源管理器);3、在终端或输出文件中显示结果:如当前运行的进程、错误信息等。(三) 进程管理设计1、进程状态与操作2、进程控制块结构PCB3、主要函数:创建进程、撤销进程(四) 资源管理设计1、主要数据结构RCB2、请求资源3、释放资源(五)进程调度与时

3、钟中断设计关键:使用基于优先级的抢占式调度策略,在同一优先级内使用时间片轮转算法。参考课上ppt: 5、 实验目的:设计和实现进程与资源管理,并完成Test shell的编写,以建立系统的进程管理、调度、资源管理和分配的知识体系,从而加深对操作系统进程调度和资源管理功能的宏观理解和微观实现技术的掌握。6、 实验内容:设计与实现一个简单的进程与资源管理器,要求具有如下功能:完成进程创建、撤销和进程调度;完成多单元 (multi_unit)资源的管理;完成资源的申请和释放;完成错误检测和定时器中断功能。通过编写测试脚本(test shell)来完成对进程与资源管理器的测试。7、 实验环境(设备、元

4、器件):Windows 7、Visual Studio 20158、 实验步骤:(一) 系统功能需求分析:(二) 总体框架设计:1、 具体原理和总体工作流程分析:首先,通过test shell从测试文件中读入各种命令。然后,对命令进行分析,将用户的需求转换成调度内核函数,也就是说,通过调度进程和资源管理器,实现创建进程、撤销进程、进程调度、对资源进行管理、申请和释放资源、检测错误和定时器中断等功能,从而模拟一个操作系统对进程进行调度和对资源进行管理的过程。最后,在终端或者输出文件中,把一系列操作后的结果显示出来,包括当前运行的进程、错误信息等。2、 相关方法和算法:(1) C语言中的结构str

5、uct,用来实现PCB、RCB等(2) C语言中的指针、链表操作,用来实现将PCB和RCB加入队列尾部、从队列中删除、转移至阻塞队列等操作,以及进程的调度执行等。本实验中我们采用的带头结点的链表来实现各种操作。(3) 基于优先级的调度算法、时间片轮转调度算法、抢占式调度算法的综合应用。3、 模块调用关系:本实验中,我们组共编写了三个头文件(pcb.h、rcb.h、test_shell_data.h)和四个源文件(main.c、pcb.c、rcb.c、test_shell_data.c),因此可以分为主函数设计模块、进程管理设计模块、资源管理设计模块和test shell设计模块。在主函数模块中

6、,需要调用其他三个模块,如创建进程、展示父子子进程等操作,需要调用进程管理设计模块;调度算法的执行、展示各种队列等,需要调用test shell设计模块;在进程管理设计模块中,像销毁PCB等操作,需要执行对RCB的释放,则需调用test shell设计模块;在资源管理设计模块中,提供一些最小的操作,不调用其他模块;在test shell设计模块中,设计到对资源和进程的各种操作,需要调用资源管理设计模块和进程管理设计模块。(三) 进程管理设计模块详细设计(本部分我负责实现)我们的计划是在在进程管理设计模块中,实现关于进程的各种最基础的结构和操作,具体包括:实现PCB结构体、PCB链表、PCB子节

7、点链表;实现对PCB链表的初始化、对子节点链表的初始化、新建PCB、对PCB链表中进行删除、插入、移除(不free)、从等待和阻塞队列中获取PCB得知、打印当前PCB父节点、打印当前PCB父节点、打印当前PCB子节点链表、插入子队列的尾部、从子队列尾部删除。1、 进程状态与操作(1) 进程状态共ready/running/blocked三种状态,通过结构struct实现,代码如下:struct int running; int blocked; int ready;PCB_STATUS; /定义pcb状态的三种情况(2) 进程操作:在本次实验中,将会读进程进行以下操作,结合这些操作的具体内容和

8、所学知识,很容易考虑到通过链表来实现这些操作。创建(create): (none) -> ready撤销(destroy): running/ready/blocked -> (none)请求资源(Request): running -> blocked (当资源没有时,进程阻塞)释放资源(Release): blocked -> ready (因申请资源而阻塞的进程被唤醒)时钟中断(Time_out): running -> ready调度:ready -> running / running ->ready2、 主要数据结构实现:(1)进程控制块结

9、构PCB进程控制块PCB是进程存在的唯一标识,并且常驻内存,进程控制块中有许多信息,在本次实验中,根据我们的需求,所设计的进程控制块结构如下:结合实验指导书,我们通过结构struct实现进程控制块结构PCB,包含以下信息:PID(name)Other_resources /: resource which is occupiedStatus: Type & List/ type: ready, block, running., /List: RL(Ready list) or BL(block list)Creation_tree: Parent/ChildrenPriority: 0

10、, 1, 2 (Init, User, System)主要代码及注释如下:struct PCB /pcb结构体 char name64; /Pname unsigned int pid; /Pid struct RCB_LIST* rcb_list; /Other resources struct PCB_LIST* parent_pcb; /父进程 struct CHILD_PCB_LIST* child_pcb; /子进程 int state; /Type&List int priority; /0,1,2;(3) 实现一个PCB的链表,方便后面的操作:struct PCB_LIS

11、T /pcb链表 struct PCB pcb; struct PCB_LIST * next_pcb;(4) 实现PCB的子节点链表:struct CHILD_PCB_LIST /pcb子节点链表 struct PCB_LIST* node; struct CHILD_PCB_LIST* next_node;3、 主要操作设计实现过程(1) 初始化PCB链表(添加了头结点):void init_pcb_list(struct PCB_LIST *list) if (*list) return; struct PCB_LIST *p = (struct PCB_LIST*)malloc(siz

12、eof(struct PCB_LIST); p->next_pcb = NULL; memset(p, NULL, sizeof(struct PCB); *list = p;(2) 初始化子节点链表:void init_child_pcb_list(struct CHILD_PCB_LIST *list) if (*list) return; struct CHILD_PCB_LIST *p = (struct CHILD_PCB_LIST*)malloc(sizeof(struct CHILD_PCB_LIST); p->next_node = NULL; memset(p,

13、NULL, sizeof(struct CHILD_PCB_LIST); *list = p;(3) 创建一个新的PCB:struct PCB_LIST* create_pcb(char* name, unsigned int pid, int state, unsigned int priority,struct PCB_LIST* parent_pcb) struct PCB pcb; strcpy(,name,strlen(name); pcb.pid = pid; pcb.rcb_list = NULL; pcb.state = state; pcb.priority

14、= priority; pcb.parent_pcb = parent_pcb; pcb.child_pcb = NULL; struct PCB_LIST* pcb_node = (struct PCB_LIST*)malloc(sizeof(struct PCB_LIST); pcb_node->pcb = pcb; pcb_node->next_pcb = NULL; return pcb_node;(4) 从PCB链表中进行删除:void destory_from_pcb_list(struct PCB_LIST* list, char *name) struct PCB_

15、LIST* pr_temp, *temp; pr_temp = temp = list; int ret = 1; while (temp) if (!strcmp(name, temp->) && ret) release_resource(temp); pr_temp = temp = list; ret = 0; if (!strcmp(name, temp->) pr_temp->next_pcb = temp->next_pcb; free(temp); return; pr_temp = temp; temp

16、= temp->next_pcb; (5)插入pcb链表:void insert_into_pcb_list(struct PCB_LIST* list, struct PCB_LIST*node) if (!*list) init_pcb_list(list); struct PCB_LIST *pr_temp, *temp; pr_temp = temp = *list; while (temp) pr_temp = temp; temp = temp->next_pcb; pr_temp->next_pcb = node;(5) 从PCB链表中移除,并不释放该PCB占用

17、的空间:void delete_from_pcb_list(struct PCB_LIST* list, char *name) struct PCB_LIST* pr_temp, *temp; pr_temp = temp = list; while (temp) if (!strcmp(name, temp->) pr_temp->next_pcb = temp->next_pcb; return; pr_temp = temp; temp = temp->next_pcb; (6) 从等待和阻塞队列中获取PCB的地址:struct PCB_LIST

18、* get_pcb(char* name) struct PCB_LIST* temp; for (int i = 2; i >= 0; i-) temp = READY_LISTi->next_pcb; while (temp) if (!strcmp(temp->, name) return temp; temp = temp->next_pcb; if (BLOCKED_LIST) temp = BLOCKED_LIST->next_pcb; while (temp) if (!strcmp(temp->, name)

19、return temp; temp = temp->next_pcb; return NULL;(7) 打印当前PCB的父节点void show_pcb_parent(struct PCB_LIST* node) printf("%s parent node is %s n", node->, node->pcb.parent_pcb->);(8) 打印当前PCB的子节点链表void show_pcb_child(struct PCB_LIST* node) printf("%s child is "

20、;, node->); struct CHILD_PCB_LIST* temp = node->pcb.child_pcb; if (temp) temp = temp->next_node; while (temp) printf(" -> |%s|", temp->node->); temp = temp->next_node; printf("n");(9) 插入子队列的尾部void insert_into_child_pcb_list(struct CHILD_PCB_LI

21、ST* list, struct PCB_LIST*node) if (!*list) init_child_pcb_list(list); struct CHILD_PCB_LIST *pr_temp, *temp; pr_temp = temp = *list; while (temp) pr_temp = temp; temp = temp->next_node; struct CHILD_PCB_LIST *p = (struct CHILD_PCB_LIST*)malloc(sizeof(struct CHILD_PCB_LIST); p->node = node; p-

22、>next_node = NULL; pr_temp->next_node = p;(10) 从子队列尾部进行删除void delete_from_child_pcb_list(struct CHILD_PCB_LIST* list, char *name) struct CHILD_PCB_LIST* pr_temp, *temp; if (!list) return; pr_temp = list; temp = pr_temp->next_node; while (temp) if (!strcmp(name, temp->node->) p

23、r_temp->next_node = temp->next_node; return; pr_temp = temp; temp = temp->next_node; (四) 其他模块设计(组内其他人设计)1、 Test shell设计Test shell将调度我们设计的进程与资源管理器,从而完成测试,具有以下功能:(1)从终端或者测试文件读取命令;(2)将用户需求转换成调度内核函数(即调度进程和资源管理器);(3)在终端或输出文件中显示结果:如当前运行的进程、错误信息等。2、 资源管理设计与进程管理设计的思路和流程相似,首先是设计好各类数据结构,包括RCB结构体、RCB等

24、待队列链表、系统RCB结构体、系统RCB链表、RCB链表。之后是实现好各类与RCB有关的基础操作,包括初始化前面设计的各种链表、新建RCB,以及对链表进行插入、删除、移除等操作,还有显示RCB队列的操作。3、 实验进程调度与时钟中断设计核心思想即时间片轮转调度算法、优先级调度算法、抢占式算法的综合应用,设计到对前面各模块的调用。9、 实验数据及结果分析:将实验指导书中给出的测试命令放到测试文件test.txt中,程序从该文件读取命令,并将执行结果输出到屏幕,如下图所示:上图结果与试验指导书中给出的预期输出结果是一致的,说明实验成功。具体的结果分析:为了更易于观察,我们可以注释掉读文件的操作,让

25、程序从键盘输入读取命令,每步命令的解释及相关执行结果截图如下:cr x 1 /创建优先级为1的进程x,应显示“* the x is running”cr p 1 /创建优先级为1的进程p,应显示“* the x is running”cr q 1 /创建优先级为1的进程q,应显示“* the x is running”cr r 1 /创建优先级为1的进程r,应显示“* the x is running”经过以上四条指令,就绪队列中优先级1的队列中应依次为x、p、q、r,可用资源数应该都是总的资源数,执行结果、就绪队列、资源队列情况见下图:to /一个时间片结束,应去执行p,显示“* the p

26、 is running”同时,x进程PCB将进入优先级为0的就绪队列,如下图:req 2 1 /为当前进程x申请1个R2资源,显示不变输出显示不变,但是可用资源数目会发生变化,如下图:to /一个时间片结束,应去执行q,显示“* the q is running”req R3 3 /为当前进程q申请3个R3资源,显示不变过程中截图如下,可用资源数目进一步减小: to /一个时间片结束,应去执行r,显示“* the r is running”req R4 3 /为当前进程x申请3个R4资源,显示不变to /一个时间片结束,应去执行优先级为0的就绪队列中的第一个进程x,显示“* the x is

27、running”to指令后截图如下,包括此时就绪队列的情况,所有进程的PCB都在优先级为0的就绪队列中:to /一个时间片结束,应去执行p,显示“* the p is running”,x移到优先级0就绪队列的结尾新的优先级为0的就绪队列截图如下:下面的两条指令分别为当前进程申请资源,申请不到足够的资源,相应进程则会进入阻塞队列。req R3 1 /p申请1个R3,但R3已经全部给了q,因此p被阻塞,进入阻塞队列,当前转去执行原来在p后的q进程,显示“* the q is running”显示及阻塞队列如下: req R4 2 /q申请2个R4,但R4已经只剩下1个,因此q被阻塞,进入阻塞队列

28、,当前转去执行原来在q后的r进程,显示“* the r is running”req R2 2 /r申请2个R2,但R2已经只剩下1个,因此r被阻塞,进入阻塞队列,当前转去执行原来在r后的x进程,显示“* the x is running”以上两步过后,阻塞队列及就绪队列截图如下:to /一个时间片结束,就绪队列中只有x,因此仍然执行x,显示“* the x is running” de q /撤销q进程,将释放q进程占用的3个R3资源,前面因为申请不到R3资源而被阻塞的p进程将重新回到就绪队列,位于x的后面,显示不变to /一个时间片结束,应去执行p,显示“* the p is runnin

29、g”to /一个时间片结束,应去执行x,显示“* the x is running”经过以上四条指令,就绪队列中优先级0的队列中应依次为x、p,阻塞队列中应该只有r,如下图: 至此,详细的每步分析完毕,实验成功。10、 实验结论:本次实验过程中,我组成员分工明确,在熟练掌握课堂知识的基础上,使用c语言模拟了操作系统对进程和资源的管理,成功地实现了基于优先级和时间片轮转的抢占式调度算法,实验结果与预期相同,很好地完成了本次实验11、 总结及心得体会:(1) 链表、指针的掌握和应用十分重要;(2) 将总的任务划分成各个模块,实现各个模块后再总体实现,可以提高效率;(3) 在程序中增加一些出错处理的

30、提示信息,有利于提高调试过程的效率。12、 对本实验过程及方法、手段的改进建议:可以增加难度更大的功能,如模拟进程中断后,返回断点继续执行等。 报告评分: 指导教师签字:电 子 科 技 大 学实 验 报 告学生姓名:郫县LBJ 学号:66 指导教师:温柔可爱的刘杰彦实验地点:主楼A2-413 实验时间:2017年6月2日一、 实验室名称:计算机学院主楼机房二、 实验项目名称:内存地址转化实验三、 实验学时:2四、 实验原理:(一) 逻辑地址到线性地址的转换1、 逻辑地址、段标识符、索引号、GDT、LDT、T1字段、段描述符、Base字段、线性地址等概念;2、 GDTR、LDTR等相关寄存器知识

31、;(以上两条在实验指导书中很详细,篇幅较长,不做粘贴了)3、 逻辑地址到线性地址的转换过程从逻辑地址到线性地址的转换过程,如下图所示(以T1=1为例,此时从段选择符中分离出段描述符和T1字段,T1=1,表明段描述符存放在LDT中);(1)从GDTR中获得GDT的地址,从LDTR中获得LDT在GDT中的偏移量,查找GDT,从中获取LDT的起始地址;(2)从DS中的高13位获取DS段在LDT中索引位置,查找LDT,获取DS段的段描述符,从而获取DS段的基地址;(3)根据DS段的基地址段内偏移量,获取所需单元的线性地址。、(二) 线性地址到物理地址的转换1、 物理地址的概念;(不做粘贴了)2、 将线

32、性地址转换成物理地址的步骤:(1)、因为页目录表的地址放在CPU的cr3寄存器中,因此首先从cr3中取出进程的页目录表地址(操作系统负责在调度进程的时候,已经把这个地址装入对应寄存器);(2)、根据线性地址前十位,在页目录表中,找到对应的索引项,因为引入了二级管理模式,页目录中的项,不是页的地址,而是一个页表的起始地址。(3)、查找页表,根据线性地址的中间十位,在页表中找到数据页的起始地址;(4)、将页的起始地址与页内偏移量(即线性地址中最后12位)相加,得到最终我们想要的物理地址;五、 实验目的:(1)掌握计算机的寻址过程(2)掌握页式地址地址转换过程(3)掌握计算机各种寄存器的用法六、 实

33、验内容:本实验运行一个设置了全局变量的循环程序,通过查看段寄存器,LDT表,GDT表等信息,经过一系列段、页地址转换,找到程序中该全局变量的物理地址。七、 实验器材(设备、元器件):计算机、Linux内核(0.11)+Bochs虚拟机八、 实验步骤:1、 点击bochs.exe安装bochs。2、 拷贝bootimage-0.11-hd、diska.img、hdc-0.11-new.img、mybochsrc-hd.bxrc至安装目录。3、 在安装目录中找到bochsdbg.exe程序,并运行。4、 在弹出的界面中,点击“Load”加载配置文件“mybochsrc-hd.bxrc”。随后,点击

34、“Start”启动Bochs虚拟机。 5、 虚拟机启动后,出现两个窗口,一个为Bochs控制窗口(Console),另一个为Linux操作系统运行窗口(主显示窗口Display)。6、 在控制窗口输入“c”后回车,加载Linux操作系统。 7、 在Linux操作系统中,使用vi工具编写mytest2.c源文件。随后执行“gcc -o mytest2 mytest2.c”命令编译并生成“mytest2”可执行文件。实验中所使用的C语言代码如下:#include <stdio.h>int j = 0x;int main() printf("the address of j i

35、s 0x%xn", &j); while(j); printf("program terminated normally!n"); return 0;8、 在Linux操作系统中,运行“./mytest2”可执行文件,结果如下:由此可以看出,在“while(j)”处进入死循环,程序的第二条输出语句不会被执行。9、 先关闭bochs和虚拟机,再右键mybochsrc-hd.bxrc,选择debugger,点击start,在console界面输入c后回车,在display界面中再次输入./mytest2,运行之前写好分程序,再回到console界面进行Ctrl

36、+c操作: 10、 在控制窗口中输入sreg命令,查看段的具体信息。根据ds段的信息是可以确定索引号为标蓝的13位,即索引号为02H,TI为标红的1位,对应TI=1,因此可知段描述符放在LDT中,并且为LDT表的第三项。0x0017=0000 0000 0001 0111B11、 查看LDTR寄存器,其中存放了LDT在GDT的位置,可知索引号为标蓝的13位,即索引为0DH,表示LDT起始地址存放在GDT的第14项。0x0068=0000 0000 0110 1000B12、 查看GDTR寄存器,其中存放了GDT在内存中的起始地址5CB8H:13、 由上图可知,GDT在内存中的起始地址为5CB8H,因为每一个段描述符由8个字节组成,则LDT的首地址为:(GDTR)+0x0D*8 = 0x5CB8 + 0x0D*8 = 0x5D20执行xp /2w 0x5cb8+0x0d*

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论