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

下载本文档

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

文档简介

操作系统实验报告学院:计算机与通信工程学院专业:计算机科学与技术班级:学号:姓名:指导教师:成绩: 2014年 1 月 1 日实验一 线程的状态和转换(5分)1 实验目的和要求目的:熟悉线程的状态及其转换,理解线程状态转换与线程调度的关系。要求:(1)跟踪调试EOS线程在各种状态间的转换过程,分析EOS中线程状态及其转换的相关源代码;(2)修改EOS的源代码,为线程增加挂起状态。2 完成的实验内容2.1 EOS线程状态转换过程的跟踪与源代码分析(分析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单步调试直到此函数的最后,然后再从快速监视对话框中观察“*Thread”表达式的值。此时State域的值为0(Zero),双向链表项StateListEntry的Next和Prev指针的值都为0,说明这个线程已经处于游离状态,并已不在任何线程状态的队列中。仔细阅读PspUnwaitThread函数中的源代码,理解这些源代码是如何改变线程状态的。 (6)按F5继续执行,在PspReadyThread函数中的断点处中断。按F10单步调试直到此函数的最后,然后再从快速监视对话框中观察“*Thread”表达式的值。此时State域的值为1(Ready),双向链表项StateListEntry的Next和Prev指针的值都不为0,说明这个线程已经处于就绪状态,并已经被放入优先级为24的就绪队列中 3.线程由运行状态进入就绪状态 (1)按F5继续执行,在PspSelectNextThread函数中的断点处中断。在快速监视对话框中查看“*PspCurrentThread”表达式的值,观察当前占用处理器的线程的情况。其中State域的值为2(Running),双向链表项StateListEntry的Next和Prev指针的值都为0,说明这个线程仍然处于运行状态,由于只能有一个处于运行状态的线程,所以这个线程不在任何线程状态的队列中;StartAddr域的值为LoopThreadFunction,说明这个线程就是loop线程。注意,在本次断点被命中之前,loop线程就已经被中断执行了,并且其上下文已经保存在线程控制块中。 (2)按F10单步调试,直到对当前线程的操作完成(也就是花括号中的操作完成)。再从快速监视对话框中查看“*PspCurrentThread”表达式的值。其中State域的值为1(Ready),双向链表项StateListEntry的Next和Prev指针的值都不为0,说明loop线程已经进入了就绪状态,并已经被放入优先级为8的就绪队列中。仔细阅读PspSelectNextThread函数这个花括号中的源代码,理解这些源代码是如何改变线程状态的,并与PspReadyThread函数中的源代码进行比较,说明这两段源代码的异同,体会为什么在这里不能直接调用PspReadyThread函数。 4.线程由就绪状态进入运行状态 (1)按F5继续执行,在PspUnreadyThread函数中的断点处中断。在快速监视对话框中查看“*Thread”表达式的值。其中State域的值为1(Ready),双向链表项StateListEntry的Next和Prev指针的值都不为0,说明这个线程处于就绪状态,并在优先级为24的就绪队列中;StartAddr域的值为IopConsoleDispatchThread,说明这个线程就是控制台派遣线程。(2)关闭快速监视对话框后,在“调用堆栈”窗口中激活PspSelectNextThread函数对应的堆栈项,可以看到在PspSelectNextThread函数中已经将PspCurrentThread全局指针指向了控制台派遣线程,并在调用PspUnreadyThread函数后,将当前线程的状态改成了Running。(3)在“调用堆栈”窗口中激活PspUnreadyThread函数对应的堆栈项,然后按F10单步调试,直到返回PspSelectNextThread函数并将线程状态修改为Running。再从快速监视对话框中查看“*PspCurrentThread”表达式的值,观察当前占用处理器的线程的情况。其中State域的值为2(Running),双向链表项StateListEntry的Next和Prev指针的值都为0,说明控制台派遣线程已经处于运行状态了。接下来,会将该线程的上下文从线程控制块(TCB)复制到处理器的各个寄存器中,处理器就可以从该线程上次停止运行的位置继续运行 5.线程由运行状态进入阻塞状态. (1)按F5继续执行,在PspWait函数中的断点处中断。在快速监视对话框中查看“*PspCurrentThread”表达式的值,观察当前占用处理器的线程的情况。其中State域的值为2(Running),双向链表项StateListEntry的Next和Prev指针的值都为0,说明这个线程仍然处于运行状态;StartAddr域的值为IopConsoleDispatchThread,说明这个线程就是控制台派遣线程。(2)按F10单步调试,直到左侧的黄色箭头指向代码第248行。再从快速监视对话框中查看“*PspCurrentThread”表达式的值。其中State域的值为3(Waiting),双向链表项StateListEntry的Next和Prev指针的值都不为0,说明控制台派遣线程已经处于阻塞状态了,并在某个同步对象的等待队列中。第248行代码可以触发线程调度功能,会中断执行当前已经处于阻塞状态的控制台派遣线程,并将处理器上下文保存到该线程的线程控制块。2.2为线程增加挂起状态的实现(给出实现方法的简要描述、源代码、测试和结果等) 1.为线程增加挂起状态 (1)删除之前添加的所有断点。 (2)按F5启动调试。 (3)待EOS启动完毕,在EOS控制台中输入命令“loop”后按回车。此时可以看到loop线程的执行计数在不停增长,说明loop线程正在执行。记录下loop线程的ID。 (4)按Ctrl+F2切换到控制台2,输入命令“suspend 31”(如果loop线程的ID是31)后按回车。命令执行成功的结果如下图所示。 (5)按Ctrl+1切换回控制台1,可以看到由于loop线程已经成功被挂起,其执行计数已经停止增长了。此时占用处理器的是EOS中的空闲线程。 2.完成Resume原语后,可以先使用suspend命令挂起loop线程,然后在控制台2中输入命令“Resume 31”(如果loop线程的ID是31)后按回车。命令执行成功的结果如下图所示。如果切换回控制台1后,发现loop线程的执行计数恢复增长就说明Resume原语可以正常工作。设计代码STATUSPsResumThread(IN HANDLE hThread)STATUS Status;BOOL IntState;PTHREAD Thread;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);return Status;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原语。设计思路和流程图:main函数开始创建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启动调试。OS Lab 会首先弹出一个调试异常对话框。 4. 在调试异常对话框中选择“否”,继续执行。 5. 立即激活虚拟机窗口查看生产者消费者同步执行的过程,如图 13-2。 6. 待应用程序执行完毕后,结束此次调试。1. 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.2 EOS信号量工作过程的跟踪与源代码分析(分析EOS信号量实现的核心源代码,简要阐述其实现方法;给出在本部分实验过程中完成的主要工作,包括调试、跟踪与思考等) EOS的P、V原语实现是PsWaitForSemaphore、PsReleaseSemaphore,这两个函数使用KeEnableInterrupts开关中断来实现原语操作。PsWaitForSemaphore流程图:PsReleaseSemaphore函数的流程图:2.3支持等待超时唤醒和批量释放功能的EOS信号量实现(给出实现方法的简要描述、源代码、测试和结果等) 修改 PsWaitForSemaphore函数,先用计数值和0 比较,当计数值大于0时,将计数值减1后直接返回成功;当计数值等于 0 时,调用 PspWait 函数阻塞线程的执行(将参数 Milliseconds 做为 PspWait 函数的第二个参数,并使用PspWait函数的返回值做为返回值)。修改PsWaitForSemaphore函数如下添加支持超时。STATUSPsWaitForSemaphore(IN PSEMAPHORE Semaphore,IN ULONG Milliseconds)BOOL IntState;ASSERT(KeGetIntNesting() = 0); IntState = KeEnableInterrupts(FALSE); STATUS ret;if (Semaphore-Count 0) Semaphore-Count-;ret = STATUS_SUCCESS; else ret = PspWait(&Semaphore-WaitListHead, Milliseconds);KeEnableInterrupts(IntState); /return ret;修改PsReleaseSemaphore函数如下添加批量释放支持。STATUSPsReleaseSemaphore(IN PSEMAPHORE Semaphore,IN LONG ReleaseCount,OUT PLONG PreviousCount)STATUS Status;BOOL IntState;IntState = KeEnableInterrupts(FALSE); if (Semaphore-Count + ReleaseCount Semaphore-MaximumCount) Status = STATUS_SEMAPHORE_LIMIT_EXCEEDED; else if (NULL != PreviousCount) *PreviousCount = Semaphore-Count;int i;for(i = ReleaseCount; i-;) Semaphore-Count+;if (Semaphore-Count WaitListHead, STATUS_SUCCESS);PspThreadSchedule();Status = STATUS_SUCCESS;KeEnableInterrupts(IntState); return Status;3 其他需要说明的问题实验三 时间片轮转调度(5分)1 实验目的和要求目的:理解进程(线程)调度的执行时机和过程,掌握调度程序实现的基本方法。要求:(1)跟踪调试EOS的线程调度程序,分析EOS基于优先级的抢占式调度的源代码;(2)修改EOS的调度程序,添加时间片轮转调度。2 完成的实验内容2.1 EOS基于优先级的抢占式调度工作过程的跟踪与源代码分析(分析EOS基于优先级的抢占式调度的核心源代码,简要阐述其实现方法;给出在本部分实验过程中完成的主要工作,包括调试、跟踪与思考等)实验使用EOS提供的rr命令观察时间片的轮转。1.准备实验(1)启动OS Lab。(2)新建一个EOS Kernel项目。2.阅读控制台命令“rr”相关的源代码 (1)按F7生成在本实验3.1中创建的EOS Kernel项目。(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)激活OS Lab窗口后按F5使第0个新建的线程继续执行,又会在断点处中断。再次激活虚拟机窗口,可以看到第0个新建的线程已经在控制台中输出了第一轮循环的内容。可以多按几次F5查看每轮循环输出的内容。b) 调试当前线程被抢先的情况(1)选择“调试”菜单中的“删除所有断点”,删除之前添加的所有断点。(2)在ps/sched.c文件的PspSelectNextThread函数的第395行添加一个断点。(3)按F5继续执行,激活虚拟机窗口,可看到第0个新建的线程正在执行。(4)在虚拟机窗口中按下一次空格键,EOS会在之前添加的断点处中断。(5)在“监视”窗口中查看就绪位图的值为1000000000000000100000001,说明此时在优先级为24的就绪队列中存在就绪线程。在“监视”窗口中添加表达式“ListGetCount(&PspReadyListHeads24)”,其值为1,说明优先级为24的就绪队列中只有一个就绪线程。扫描就绪位图后获得的最高优先级的值HighestPriority也就应该是24。(6)按F10单步调试一次,执行的语句会将当前正在执行的第0个新建的线程,放入优先级为8的就绪队列的队首。“监视”窗口中显示的优先级为8的就绪队列中的线程数量就会增加1,变为20。(7)继续按F10单步调试,直到在第444行中断执行,注意观察线程调度执行的每一个步骤。

温馨提示

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

评论

0/150

提交评论