计算机操作系统-实验报告_第1页
计算机操作系统-实验报告_第2页
计算机操作系统-实验报告_第3页
计算机操作系统-实验报告_第4页
计算机操作系统-实验报告_第5页
已阅读5页,还剩9页未读 继续免费阅读

下载本文档

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

文档简介

操作系统实验报告学院:计算机与通信工程学院专业:计算机科学与技术班级:学号:姓名:指导教师:成绩:2014年1月1日PAGE1实验一线程的状态和转换(5分)1实验目的和要求目的:熟悉线程的状态及其转换,理解线程状态转换与线程调度的关系。要求:(1)跟踪调试EOS线程在各种状态间的转换过程,分析EOS中线程状态及其转换的相关源代码;(2)修改EOS的源代码,为线程增加挂起状态。2完成的实验内容2.1EOS线程状态转换过程的跟踪与源代码分析(分析EOS中线程状态及其转换的核心源代码,说明EOS定义的线程状态以及状态转换的实现方法;给出在本部分实验过程中完成的主要工作,包括调试、跟踪与思考等)1.EOS准备了一个控制台命令“loop”,这个命令的命令函数是ke/sysproc.c文件中的ConsoleCmdLoop函数(第797行,在此函数中使用LoopThreadFunction函数(第755行)创建了一个优先级为8的线程(后面简称为“loop线程”),该线程会在控制台中不停的(死循环)输出该线程的ID和执行计数,执行计数会不停的增长以表示该线程在不停的运行。loop命令执行的效果可以参见下图:2.线程由阻塞状态进入就绪状态(1)在虚拟机窗口中按下一次空格键。(2)此时EOS会在PspUnwaitThread函数中的断点处中断。在“调试”菜单中选择“快速监视”,在快速监视对话框的表达式编辑框中输入表达式“*Thread”,然后点击“重新计算”按钮,即可查看线程控制块(TCB)中的信息。其中State域的值为3(Waiting),双向链表项StateListEntry的Next和Prev指针的值都不为0,说明这个线程还处于阻塞状态,并在某个同步对象的等待队列中;StartAddr域的值为IopConsoleDispatchThread,说明这个线程就是控制台派遣线程。(3)关闭快速监视对话框,激活“调用堆栈”窗口。根据当前的调用堆栈,可以看到是由键盘中断服务程序(KdbIsr)进入的。当按下空格键后,就会发生键盘中断,从而触发键盘中断服务程序。在该服务程序的最后中会唤醒控制台派遣线程,将键盘事件派遣到活动的控制台。(4)在“调用堆栈”窗口中双击PspWakeThread函数对应的堆栈项。可以看到在此函数中连续调用了PspUnwaitThread函数和PspReadyThread函数,从而使处于阻塞状态的控制台派遣线程进入就绪状态。(5)在“调用堆栈”窗口中双击PspUnwaitThread函数对应的堆栈项,先来看看此函数是如何改变线程状态的。按F10单步调试直到此函数的最后,然后再从快速监视对设计代码STATUSPsResumThread( INHANDLEhThread ){ STATUSStatus; BOOLIntState; PTHREADThread; Status=ObRefObjectByHandle(hThread,PspThreadType,(PVOID*)&Thread); if(EOS_SUCCESS(Status)){ IntState=KeEnableInterrupts(FALSE); //关中断 if(Zero==Thread->State){ ListRemoveEntry(&Thread->StateListEntry); PspReadyThread(Thread); PspThreadSchedule(); Status=STATUS_SUCCESS; }else{ Status=STATUS_NOT_SUPPORTED; } KeEnableInterrupts(IntState); //开中断 ObDerefObject(Thread); } returnStatus;}1.首先调用ListRemoveEntry函数将线程从挂起线程队列中移除。2.然后调用PspReadyThread函数将线程恢复为就绪状态。3.最后调用PspThreadSchedule宏函数执行线程调度,让刚刚恢复的线程有机会执行。3其他需要说明的问题

实验二进程的同步(7分)1实验目的和要求目的:理解进程同步的原理和意义,掌握信号量的实现方法和应用。要求:(1)使用EOS的信号量,实现生产者-消费者问题;(2)跟踪调试EOS信号量的工作过程,分析EOS信号量实现的源代码;(3)修改EOS信号量的实现代码,使之支持等待超时唤醒和批量释放功能。2完成的实验内容2.1使用EOS的信号量实现生产者-消费者问题(简要说明使用EOS的信号量解决生产者-消费者问题的实现方法;给出在本部分实验过程中完成的主要工作,包括调试、跟踪、测试与思考等)EOS使用CreateThread函数创建线程,使用CreateMutex、CreateSemaphore创建信号量。WaitForSingleObject与ReleaseMutex、ReleaseSemaphore函数相当于P、V原语。设计思路和流程图:mainmain函数开始创建Mutex对象创建Empty信号量对象创建Full信号量对象创建生产者线程创建消费者线程等待生产者线程和消费者线程结束关闭句柄main函数结束Producer函数开始生产完毕?等待Empty信号量对象等待Mutex对象生产一个产品,占用一个缓冲区循环向后移动缓冲区指针释放Mutex对象释放Full信号量对象等待500毫秒Producer函数结束Consumer函数开始消费完毕毕?等待Full信号量对象等待Mutex对象消费一个产品,清空一个缓冲区循环向后移动缓冲区指针释放Mutex对象释放Empty信号量对象前10个产品?等待2000毫秒等待100毫秒Consumer函数结束按照下面的步骤查看生产者-消费者同步执行的过程:1.使用pc.c文件中的源代码,替换之前创建的EOS应用程序项目中EOSApp.c文件内的源代码。2.按F7生成修改后的EOS应用程序项目。3.按F5启动调试。OSLab会首先弹出一个调试异常对话框。4.在调试异常对话框中选择“否”,继续执行。5.立即激活虚拟机窗口查看生产者-消费者同步执行的过程,如图13-2。6.待应用程序执行完毕后,结束此次调试。Mutex、Empty、Full三个信号量的初始值分别为1、10、0,当存在一个生产者线程访问缓冲池时,首先对Empty减1,如果大于0,则说明还有剩余缓冲区可以让生产者放入产品,否则生产者线程进入等待队列;再对Mutex减1,如果大于等于0,则说明没有线程占用缓冲池,否则生产者线程进入等待队列。生产完产品后,对Mutex加1,解除封锁;再对Full加1,说明生产了一个产品占用了一个缓冲区。消费者线程同理,对信号量的操作顺序与生产者线程相反。不能对这三个同步对象的操作改变顺序,否则可能造成死锁。2.因为临界资源的访问限制,程序中限定了缓冲池的大小为10,只有缓冲池有空余时生产者才能向里边放产品,同时只有缓冲池有产品时消费者才能向外取东西。当生产者生产了13号产品后,共生产了从0到13的14个产品,但是只消费了从0到3的4个产品,所以缓冲池中的10个缓冲区就都被占用了,所以不能继续生产14号产品,而要等到消费者消费掉一个产品后,缓冲池有空余位置,才能继续生产14号产品。当生产者线程生产了13号产品后,此时Full信号量的值为10,而Empty信号量的值为0,此时若生产者线程要再生产一个产品,先对Empty减1,此时Empty值小于零,生产者线程进入等待队列;而此时若有一个消费者线程要消费一个产品,先对Full减1,此时Full值为9,大于0,如果没有线程占用缓冲池,消费者可以消费一个产品。这样,生产者和消费者就能实现同步过程了。2.2EOS信号量工作过程的跟踪与源代码分析(分析EOS信号量实现的核心源代码,简要阐述其实现方法;给出在本部分实验过程中完成的主要工作,包括调试、跟踪与思考等)EOS的P、V原语实现是PsWaitForSemaphore、PsReleaseSemaphore,这两个函数使用KeEnableInterrupts开关中断来实现原语操作。PsWaitForSemaphore流程图:PsReleaseSemaphore函数的流程图:2.3支持等待超时唤醒和批量释放功能的EOS信号量实现(给出实现方法的简要描述、源代码、测试和结果等)修改PsWaitForSemaphore函数,先用计数值和0比较,当计数值大于0时,将计数值减1后直接返回成功;当计数值等于0时,调用PspWait函数阻塞线程的执行(将参数Milliseconds做为PspWait函数的第二个参数,并使用PspWait函数的返回值做为返回值)。修改PsWaitForSemaphore函数如下添加支持超时。STATUSPsWaitForSemaphore( INPSEMAPHORESemaphore, INULONGMilliseconds ){ BOOLIntState; ASSERT(KeGetIntNesting()==0); IntState=KeEnableInterrupts(FALSE); STATUSret; if(Semaphore->Count>0){ Semaphore->Count--; ret=STATUS_SUCCESS; }else{ ret=PspWait(&Semaphore->WaitListHead,Milliseconds); } KeEnableInterrupts(IntState);/ returnret;}修改PsReleaseSemaphore函数如下添加批量释放支持。STATUSPsReleaseSemaphore( INPSEMAPHORESemaphore, INLONGReleaseCount, OUTPLONGPreviousCount ){ STATUSStatus; BOOLIntState; IntState=KeEnableInterrupts(FALSE); if(Semaphore->Count+ReleaseCount>Semaphore->MaximumCount){ Status=STATUS_SEMAPHORE_LIMIT_EXCEEDED; }else{ if(NULL!=PreviousCount){ *PreviousCount=Semaphore->Count; } inti; for(i=ReleaseCount;i--;){ Semaphore->Count++; if(Semaphore->Count<=0){ PspWakeThread(&Semaphore->WaitListHead,STATUS_SUCCESS); } } PspThreadSchedule(); Status=STATUS_SUCCESS; } KeEnableInterrupts(IntState); returnStatus;}3其他需要说明的问题

实验三时间片轮转调度(5分)1实验目的和要求目的:理解进程(线程)调度的执行时机和过程,掌握调度程序实现的基本方法。要求:(1)跟踪调试EOS的线程调度程序,分析EOS基于优先级的抢占式调度的源代码;(2)修改EOS的调度程序,添加时间片轮转调度。2完成的实验内容2.1EOS基于优先级的抢占式调度工作过程的跟踪与源代码分析(分析EOS基于优先级的抢占式调度的核心源代码,简要阐述其实现方法;给出在本部分实验过程中完成的主要工作,包括调试、跟踪与思考等)实验使用EOS提供的rr命令观察时间片的轮转。1.准备实验(1)启动OSLab。(2)新建一个EOSKernel项目。2.阅读控制台命令“rr”相关的源代码(1)按F7生成在本实验3.1中创建的EOSKernel项目。(2)按F5启动调试。(3)待EOS启动完毕,在EOS控制台中输入命令“rr”后按回车。3.调试线程调度程序a)调试当前线程不被抢先的情况(1)结束之前的调试。(2)在ke/sysproc.c文件的ThreadFunction函数中,调用fprintf函数的代码行(第680行)添加一个断点。(3)按F5启动调试。(4)待EOS启动完毕,在EOS控制台中输入命令“rr”后按回车。“rr”命令开始执行后,会在断点处中断。(5)查看ThreadFunction函数中变量pThreadParameter->Y的值应该为0,说明正在调试的是第0个新建的线程。(6)激活虚拟机窗口,可以看到第0个新建的线程还没有在控制台中输出任何内容,原因是fprintf函数还没有执行。(7)激活OSLab窗口后按F5使第0个新建的线程继续执行,又会在断点处中断。再次激活虚拟机窗口,可以看到第0个新建的线程已经在控制台中输出了第一轮循环的内容。可以多按几次F5查看每轮循环输出的内容。b)调试当前线程被抢先的情况(1)选择“调试”菜单中的“删除所有断点”,删除之前添加的所有断点。(2)在ps/sched.c文件的PspSelectNextThread函数的第395行添加一个断点。(3)按F5继续执行,激活虚拟机窗口,可看到第0个新建的线程正在执行。(4)在虚拟机窗口中按下一次空格键,EOS会在之前添加的断点处中断。(5)在“监视”窗口中查看就绪位图的值为1000000000000000100000001,说明此时在优先级为24的就绪队列中存在就绪线程。在“监视”窗口中添加表达式“ListGetCount(&PspReadyListHeads[24])”,其值为1,说明优先级为24的就绪队列中只有一个就绪线程。扫描就绪位图后获得的最高优先级的值HighestPriority也就应该是24。(6)按F10单步调试一次,执行的语句会将当前正在执行的第0个新建的线程,放入优先级为8的就绪队列的队首。“监视”窗口中显示的优先级为8的就绪队列中的线程数量就会增加1,变为20。(7)继续按F10单步调试,直到在第444行中断执行,注意观察线程调度执行的每一个步骤。此时,正在执行的第0个新建的线程已经进入了“就绪”状态,让出了CPU。线程调度程序接下来的工作就是选择优先级最高的非空就绪队列的队首线程作为当前运行线程,也就是让优先级为24的线程在CPU上执行。(8)按F10单步调试一次,当前线程PspCurrentThread指向了优先级为24的线程。可以在“快速监视”窗口中查看表达式“*PspCurrentThread”的值,注意线程控制块中StartAddr域的值为IopConsoleDispatchThread函数(在文件io/console.c中定义),说明这个优

温馨提示

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

最新文档

评论

0/150

提交评论