哈尔滨工程大学操作系统 实验四进程的同步

上传人:桔**** 文档编号:469509054 上传时间:2022-11-16 格式:DOCX 页数:15 大小:248.80KB
返回 下载 相关 举报
哈尔滨工程大学操作系统 实验四进程的同步_第1页
第1页 / 共15页
哈尔滨工程大学操作系统 实验四进程的同步_第2页
第2页 / 共15页
哈尔滨工程大学操作系统 实验四进程的同步_第3页
第3页 / 共15页
哈尔滨工程大学操作系统 实验四进程的同步_第4页
第4页 / 共15页
哈尔滨工程大学操作系统 实验四进程的同步_第5页
第5页 / 共15页
点击查看更多>>
资源描述

《哈尔滨工程大学操作系统 实验四进程的同步》由会员分享,可在线阅读,更多相关《哈尔滨工程大学操作系统 实验四进程的同步(15页珍藏版)》请在金锄头文库上搜索。

1、操作系统实验报告课程名称操作系统实验课程编号0920311实验项目名称进程的同步学号年级2013姓名徐大亮专业软件工程学生所在学院软件学院指导教师刘刚实验室名称地点计算机软件第二实验室21#427哈尔滨工程大学软件学院第四讲 进程的同步、实验概述1. 实验名称:进程的同步2. 实验目的:(1) 使用EOS的信号量,编程解决生产者一消费者问题,理解进程同步的意义。(2) 调试跟踪EOS信号量的工作过程,理解进程同步的原理。(3) 修改EOS的信号量算法,使之支持等待超时唤醒功能(有限等待,)加深理 解进程同步的原理。3. 实验类型:验证设计4. 实验内容1 ) 准备实验2) 使用 EOS 的信号

2、量解决生产者消费者问题3) 调试 EOS 信号量的工作过程4) 修改 EOS 的信号量算法二、实验环境操作系统:windows xp编译器: Bochs 模拟器语言:C 语言工具: OSLAB三、实验过程1 准备实验按照下面的步骤准备本次实验:1. 启动 OS Lab。2. 新建一个 EOS Kernel 项目。3. 生成 EOS Kernel 项目,从而在该项目文件夹中生成 SDK 文件夹。4. 新建一个 EOS 应用程序项目。5. 使用在第3步生成的SDK文件夹覆盖EOS应用程序项目文件夹中的SDK 文件夹。2 使用 EOS 的信号量解决生产者消费者问题 在本实验文件夹中,提供了使用 EO

3、S 的信号量解决生产者消费者问题的参考 源代码文件pc.c。使用OS Lab 打开此文件(将文件拖动到 OS Lab 窗口中释放即可打开),仔细阅读 此文件中的源代码和注释,各个函数的流程图可以参见图 13-1。思考在两个线程函数( Producer 和 Consumer) 中,哪些是临界资源? 哪些代码是临界区?哪些代码是进入临界区?哪些代码是退出临界区?进入临 界区和退出临界区的代码是否成对出现? 按照下面的步骤查看生产者消费者同步执行的过程:1. 使用 pc.c 文件中的源代码,替换之前创建的 EOS 应用程序项目中 EOSApp.c 文件内的源代码。2. 按F7生成修改后的EOS应用程

4、序项目。3. 按F5启动调试。OS Lab会首先弹出一个调试异常对话框。4. 在调试异常对话框中选择“否”,继续执行。5. 立即激活虚拟机窗口查看生产者消费者同步执行的过程,如图 13-2。6. 待应用程序执行完毕后,结束此次调试。3 调试 EOS 信号量的工作过程3.1 创建信号量信号量结构体 ( SEMAPHORE ) 中的各个成员变量是由 API 函数 CreateSemaphore 的对应参数初始化的,查看 main 函数中创建 Empty 和 Full 信号量使用的参数有哪些不同,又有哪些相 同,思考其中的原因。按照下面的步骤调试信号量创建的过程:1. 按F5启动调试EOS应用项目。

5、OS Lab会首先弹出一个调试异常对话框。2. 在调试异常对话框中选择“是”,调试会中断。3. 在main函数中创建Empty信号量的代码行(第77行)EmptySemaphoreHandle = CreateSemaphore(BUFFER_SIZE, BUFFER_SIZE, NULL);添加一个断点。4. 按 F5 继续调试,到此断点处中断。5. 按 F11 调试进入 CreateSemaphore 函数。可以看到此 API 函数只是调用了 EOS 内核中的PsCreateSemaphoreObject 函数来创建信号量对象。6. 按 F11 调试进入 semaphore.c 文件中的

6、PsCreateSemaphoreObject 函数。在 此函数中,会在 EOS内核管理的内存中创建一个信号量对象(分配一块内存),而初始化信号量对象 中各个成员的操作是在 PsInitializeSemaphore 函数中完成的。7. 在semaphore.c文件的顶部查找到PsInitializeSemaphore函数的定义(第19 行),在此函数的第一行(第 39 行)代码处添加一个断点。8. 按F5继续调试,到断点处中断。观察PsInitializeSemaphore函数中用来初始 化信号量结构体成员的值,应该和传入 CreateSemaphore 函数的参数值是一致的。9. 按 F1

7、0 单步调试 PsInitializeSemaphore 函数执行的过程,查看信号量结构 体被初始化的过程。打开“调用堆栈”窗口,查看函数的调用层次。3.2 等待、释放信号量3.2.1 等待信号量(不阻塞) 生产者和消费者刚开始执行时,用来放产品的缓冲区都是空的,所以生产者在第 一次调用WaitForSingleObject 函数等待 Empty 信号量时,应该不需要阻塞就可以立即返 回。按照下面的步骤调试:1. 删除所有的断点(防止有些断点影响后面的调试)。2. 在 eosapp.c 文件的 Producer 函数中,等待 Empty 信号量的代码行(第 144 行)WaitForSingl

8、eObject(EmptySemaphoreHandle, INFINITE);添加一个断点。3. 按 F5 继续调试,到断点处中断。4. WaitForSingleObject 函数最终会调用内核中的 PsWaitForSemaphore 函数完 成等待操作。所以,在 semaphore.c 文件中 PsWaitForSemaphore 函数的第一行(第 68 行)添加一个 断点。5. 按F5继续调试,到断点处中断。6. 按 F10 单步调试,直到完成 PsWaitForSemaphore 函数中的所有操作。可以 看到此次执行并没有进行等待,只是将Empty信号量的计数减少了 1 (由10变

9、为了 9)就返回了。3.2.2 释放信号量(不唤醒)1. 删除所有的断点(防止有些断点影响后面的调试)。2. 在eosapp.c文件的Producer函数中,释放Full信号量的代码行(第152行) ReleaseSemaphore(FullSemaphoreHandle, 1, NULL);添加一个断点。3. 按 F5 继续调试,到断点处中断。4. 按 F11 调试进入 ReleaseSemaphore 函数。5. 继续按 F11 调试进入 PsReleaseSemaphoreObject 函数。6. 先使用 F10 单步调试,当黄色箭头指向第 269 行时使用 F11 单步调试,进 入 P

10、sReleaseSemaphore函数。7. 按 F10 单步调试,直到完成 PsReleaseSemaphore 函数中的所有操作。可以 看到此次执行没有唤醒其它线程(因为此时没有线程在 Full 信号量上被阻塞),只是将 Full 信号量 的计数增加了 1(由 0变为了 1)。生产者线程通过等待Empty信号量使空缓冲区数量减少了 1,通过释放Full信号 量使满缓冲区数量增加了 1,这样就表示生产者线程生产了一个产品并占用了一个缓冲区。3.2.3 等待信号量(阻塞)由于开始时生产者线程生产产品的速度较快,而消费者线程消费产品的速度较慢 所以当缓冲池中所有的缓冲区都被产品占用时,生产者在生

11、产新的产品时就会被阻塞,下面调试这 种情况。1. 结束之前的调试。2. 删除所有的断点。3. 按F5重新启动调试。OS Lab会首先弹出一个调试异常对话框。4. 在调试异常对话框中选择“是”,调试会中断。5. 在 semaphore.c 文件中的 PsWaitForSemaphore 函数的 PspWait(&Semaphore-WaitListHead, INFINITE);代码行(第78 行)添加一个断点。6. 按 F5 继续调试,并立即激活虚拟机窗口查看输出。开始时生产者、消费者 都不会被信号量阻塞,同步执行一段时间后才在断点处中断。7. 中断后,查看“调用堆栈”窗口,有 Produce

12、r 函数对应的堆栈帧,说明此 次调用是从生产者线程函数进入的。8. 在“调用堆栈”窗口中双击 Producer 函数所在的堆栈帧,绿色箭头指向等 待 Empty 信号量的代码行,查看Producer函数中变量i的值为14,表示生产者线程正在尝试生产14 号产品。9. 在“调用堆栈”窗口中双击 PsWaitForSemaphore 函数的堆栈帧,查看 Empty 信号量计数(Semaphore-Count)的值为-1,所以会调用PspWait函数将生产者线程放入 Empty 信号量的等待队列中进行等待(让出 CPU)。10. 激活虚拟机窗口查看输出的结果。生产了从0到13的14个产品,但是只消

13、费了从0到 3的 4个产品,所以缓冲池中的 10 个缓冲区就都被占用了,这与之前调试的结果是一致 的。3.2.4 释放信号量(唤醒) 只有当消费者线程从缓冲池中消费了一个产品,从而产生一个空缓冲区后,生产 者线程才会被唤醒并继续生产 14号产品。可以按照下面的步骤调试:1. 删除所有断点。2. 在eosapp.c文件的Consumer函数中,释放Empty信号量的代码行(第180 行)ReleaseSemaphore(EmptySemaphoreHandle, 1, NULL);添加一个断点。3. 按F5继续调试,到断点处中断。4. 查看Consumer函数中变量i的值为4,说明已经消费了 4

14、号产品。5. 按照 3.3.2.2 中的方法使用 F10 和 F11 调试进入 PsReleaseSemaphore 函数。6. 查看 PsReleaseSemaphore 函数中 Empty 信号量计数( Semaphore-Count) 的值为-1,和生产者线程被阻塞时的值是一致的。7. 按F10单步调试PsReleaseSemaphore函数,直到在代码行(第132行)PspWakeThread(&Semaphore-WaitListHead, STATUS_SUCCESS);处中断。 此时 Empty 信号量计数的值已经由-1 增加为了 0, 需要调用 PspWakeThread函数唤

15、醒阻塞在 Empty 信号量等待队列中的生产者线程(放入就绪队列中) ,然后调用PspSchedule 函数执行调度,这样生产者线程就得以继续执行。按照下面的步骤验证生产者线程被唤醒后,是从之前被阻塞时的状态继续执行的:1. 在 semaphore.c 文件中 PsWaitForSemaphore 函数的最后一行(第 83 行) 代码处添加一个断点。2. 按 F5 继续调试,在断点处中断。3. 查看 PsWaitForSemaphore 函数中 Empty 信号量计数(Semaphore-Count) 的值为 0,和生产者线程被唤醒时的值是一致的。4. 在“调用堆栈”窗口中可以看到是由 Producer 函数进入的。激活 Producer 函数的堆栈帧,查看Producer函数中变量i的值为14,表明之前被阻塞的、正在尝试生产14号产品 的生产者线程已经从PspWait函数返回并继续执行了。5. 结束此次调试。4. 修改EOS的信号量算法1)根据文档修改的代码如下:PsWaitForSemaphore 函数代码:STAT

展开阅读全文
相关资源
正为您匹配相似的精品文档
相关搜索

最新文档


当前位置:首页 > 学术论文 > 其它学术论文

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号