进程的同步 (2)

上传人:公**** 文档编号:513655681 上传时间:2023-10-19 格式:DOC 页数:13 大小:806.06KB
返回 下载 相关 举报
进程的同步 (2)_第1页
第1页 / 共13页
进程的同步 (2)_第2页
第2页 / 共13页
进程的同步 (2)_第3页
第3页 / 共13页
进程的同步 (2)_第4页
第4页 / 共13页
进程的同步 (2)_第5页
第5页 / 共13页
点击查看更多>>
资源描述

《进程的同步 (2)》由会员分享,可在线阅读,更多相关《进程的同步 (2)(13页珍藏版)》请在金锄头文库上搜索。

1、操作系统实 验 报 告课程名称操作系统实验实验项目名称进程的同步学号2009142212班级20100614姓名刘欣卓专业计算机科学与技术学生所在学院计算机科学与技术学院指导教师初妍实验室名称地点21#428 哈尔滨工程大学计算机科学与技术学院一、实验概述1. 实验名称第三讲 进程的同步2. 实验目的使用EOS的信号量,编程解决生产者消费者问题,理解进程同步的意义。调试跟踪EOS信号量的工作过程,理解进程同步的原理。 修改EOS的信号量算法,使之支持等待超时唤醒功能(有限等待),加深理解进程同步的原理。 3. 实验类型验证性实验、设计性试验4. 实验内容(1)准备实验启动OS Lab。新建一个

2、EOS Kernel项目。 生成EOS Kernel项目,从而在该项目文件夹中生成SDK文件夹。 新建一个EOS应用程序项目。 使用在第3步生成的SDK文件夹覆盖EOS应用程序项目文件夹中的SDK文件夹。 (2)生产者消费者同步执行的过程使用pc.c文件中的源代码,替换之前创建的EOS应用程序项目中EOSApp.c文件内的源代码。按F7生成修改后的EOS应用程序项目。按F5启动调试。OS Lab会首先弹出一个调试异常对话框。 在调试异常对话框中选择“否”,继续执行。立即激活虚拟机窗口查看生产者消费者同步执行的过程。待应用程序执行完毕后,结束此次调试。 (3) 调试EOS信号量的工作过程I 创建

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

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

5、程,查看信号量结构体被初始化的过程。打开“调用堆栈”窗口,查看函数的调用层次。 II 等待、释放信号量1、等待信号量(不阻塞)删除所有的断点。在eosapp.c文件的Producer函数中,等待Empty信号量的代码行(第144行) WaitForSingleObject(EmptySemaphoreHandle, INFINITE); 添加一个断点。 按F5继续调试,到断点处中断。WaitForSingleObject 函数最终会调用内核中的PsWaitForSemaphore函数完成等待操作。所以,在semaphore.c文件中PsWaitForSemaphore函数的第一行(第68行)添

6、加一个断点。按F5继续调试,到断点处中断。 按F10单步调试,直到完成PsWaitForSemaphore函数中的所有操作。 2、释放信号量(不唤醒)删除所有的断点。在eosapp.c文件的Producer函数中,释放Full信号量的代码行(第152行) ReleaseSemaphore(FullSemaphoreHandle, 1, NULL); 添加一个断点。 按F5继续调试,到断点处中断。 按F11调试进入ReleaseSemaphore函数。继续按F11调试进入PsReleaseSemaphoreObject函数。先使用F10单步调试,当黄色箭头指向第269行时使用F11单步调试,进入

7、PsReleaseSemaphore函数。 按F10单步调试,直到完成PsReleaseSemaphore函数中的所有操作。3、等待信号量(阻塞)结束之前的调试。删除所有的断点。按F5重新启动调试。OS Lab会首先弹出一个调试异常对话框。在调试异常对话框中选择“是”,调试会中断。 在semaphore.c文件中的PsWaitForSemaphore函数的 PspWait(&Semaphore-WaitListHead, INFINITE); 代码行(第78行)添加一个断点。按F5继续调试,并立即激活虚拟机窗口查看输出。开始时生产者、消费者都不会被信号量阻塞,同步执行一段时间后才在断点处中断。

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

9、了从0到3的4个产品,所以缓冲池中的10个缓冲区就都被占用了,这与之前调试的结果是一致的。 4、释放信号量(唤醒)删除所有断点。在eosapp.c文件的Consumer函数中,释放Empty信号量的代码行(第180行) ReleaseSemaphore(EmptySemaphoreHandle, 1, NULL); 添加一个断点。按F5继续调试,到断点处中断。查看Consumer函数中变量i的值为4,说明已经消费了4号产品。按照释放信号量(不唤醒)中的方法使用F10和F11调试进入PsReleaseSemaphore函数。查看PsReleaseSemaphore函数中Empty信号量计数(Se

10、maphore-Count)的值为-1,和生产者线程被阻塞时的值是一致的。按F10单步调试PsReleaseSemaphore函数,直到在代码行(第132行) PspWakeThread(&Semaphore-WaitListHead, STATUS_SUCCESS); 处中断。此时Empty信号量计数的值已经由-1增加为了0,需要调用PspWakeThread函数唤醒阻塞在Empty信号量等待队列中的生产者线程(放入就绪队列中),然后调用PspSchedule函数执行调度,这样生产者线程就得以继续执行。 III 验证生产者线程被唤醒后从被阻塞时的状态继续执行在semaphore.c文件中Ps

11、WaitForSemaphore函数的最后一行(第83行)代码处添加一个断点。按F5继续调试,在断点处中断。查看PsWaitForSemaphore函数中Empty信号量计数(Semaphore-Count)的值为0,和生产者线程被唤醒时的值是一致的。在“调用堆栈”窗口中可以看到是由Producer函数进入的。激活Producer函数的堆栈帧,查看Producer函数中变量i的值为14,表明之前被阻塞的、正在尝试生产14号产品的生产者线程已经从PspWait函数返回并继续执行了。结束此次调试。 (4)修改EOS的信号量算法修改PsWaitForSemaphore函数先用计数值和0比较,当计数值

12、大于0时,将计数值减1后直接返回成功;当计数值等于0时,调用PspWait函数阻塞线程的执行(将参数Milliseconds做为PspWait函数的第二个参数,并使用PspWait函数的返回值做为返回值)。在函数开始定义一个STATUS类型的变量,用来保存不同情况下的返回值,并在函数最后返回此变量的值。绝不能在原子操作的中途返回! 修改PsReleaseSemaphore函数如果被阻塞的线程数量大于等于ReleaseCount,则循环结束后,有ReleaseCount个线程会被唤醒,而且信号量计数的值仍然为0; 如果被阻塞的线程数量(可以为0)小于ReleaseCount,则循环结束后,所有被

13、阻塞的线程都会被唤醒,并且信号量的计数值ReleaseCount之前被阻塞线程的数量之前信号量的计数值。 (5)测试方法使用修改完毕的EOS Kernel项目生成完全版本的SDK文件夹,并覆盖之前的生产者消费者应用程序项目的SDK文件夹。按F5调试执行原有的生产者消费者应用程序项目,结果必须仍然与图13-2一致。如果有错误,可以调试内核代码来查找错误,然后在内核项目中修改, 将Producer函数中等待Empty信号量的代码行WaitForSingleObject(EmptySemaphoreHandle, INFINITE); 替换为while(WAIT_TIMEOUT = WaitForS

14、ingleObject(EmptySemaphoreHandle,300)printf(Producer wait for empty semaphore timeoutn); 将Consumer函数中等待Full信号量的代码行WaitForSingleObject(FullSemaphoreHandle, INFINITE);替换为while(WAIT_TIMEOUT=WaitForSingleObject(FullSemaphoreHandle,300) printf(Consumer wait for full semaphore timeoutn); 启动调试新的生产者消费者项目,查看

15、在虚拟机中输出的结果,验证信号量超时等待功能是否能够正常执行。如果有错误,可以调试内核代码来查找错误,然后在内核项目中修改。如果超时等待功能已经能够正常执行,可以考虑将消费者线程修改为一次消费两个产品,来测试ReleaseCount参数是否能够正常使用。使用实验文件夹中NewConsumer.c文件中的Consumer函数替换原有的Consumer函数。 二、实验环境Tevation OS Lab 1.0.3.9900三、 实验过程一、设计思路:1 启动OS Lab 3.1 准备实验 3.2 使用EOS的信号量解决生产者消费者问题 3.3 调试EOS信号量的工作过程 3.3.1 创建信号量 3.3.2 等待、释放信号量 3.3.2.1 等待信号量(不阻塞) 3.3.2.2 释放信号量(不唤醒) 3.3.2.3 等待信号量(阻塞) 3.3.2.4 释放信号量(唤醒) 3.4 修改EOS的信号量算法 3.4.1 要求 3.4.2 提示 3.4.3 测试方法 3.5 退出系统并保存oud文件二、 算法设计:本次实验要求修改信号量算法1、 修改PsWaitForSemaphore函数PsWaitForSemaphore函数

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 建筑/环境 > 施工组织

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