进程的同步 (2)

上传人:无*** 文档编号:158444722 上传时间:2022-10-04 格式:DOC 页数:13 大小:806.06KB
收藏 版权申诉 举报 下载
进程的同步 (2)_第1页
第1页 / 共13页
进程的同步 (2)_第2页
第2页 / 共13页
进程的同步 (2)_第3页
第3页 / 共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

16、.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函数中原有的代码段Semaphore-Count-; if (Semaphore-Count WaitListHead, INFINITE); 应被修改为:先用计数值和0比较

17、,当计数值大于0时,将计数值减1后直接返回成功;当计数值等于0时,调用PspWait函数阻塞线程的执行(将参数Milliseconds做为PspWait函数的第二个参数,并使用PspWait函数的返回值做为返回值)。 在函数开始定义一个STATUS类型的变量,用来保存不同情况下的返回值,并在函数最返回此变量的值。绝不能在原子操作的中途返回! 在EOS Kernel项目ps/sched.c文件的第190行查看PspWait函数的说明和源代码。 按要求应修改为:if (Semaphore-Count 0)Semaphore-Count-;flag=STATUS_SUCCESS;/信号量大于0,说明

18、可以为线程分配资源else flag=PspWait(&Semaphore-WaitListHead, Milliseconds);/信号量小于0,需要等待KeEnableInterrupts(IntState); / 原子操作完成,恢复中断。return flag;2、 修改PsReleaseSemaphore函数编写一个使用ReleaseCount做为计数器的循环体,来替换PsReleaseSemaphore函数中原有的代码段Semaphore-Count+;if (Semaphore-Count WaitListHead, STATUS_SUCCESS); 在循环体中完成下面的工作:1.

19、 如果被阻塞的线程数量大于等于ReleaseCount,则循环结束后,有ReleaseCount个线程会被唤醒,而且信号量计数的值仍然为0; 2. 如果被阻塞的线程数量(可以为0)小于ReleaseCount,则循环结束后,所有被阻塞的线程都会被唤醒,并且信号量的计数值ReleaseCount之前被阻塞线程的数量之前信号量的计数值。 在EOS Kernel项目ps/sched.c文件的第294行查看PspWakeThread函数的说明和源代码。在循环的过程中可以使用宏定义函数ListIsEmpty判断信号量的等待队列是否为空,例如 ListIsEmpty(&Semaphore-WaitList

20、Head) 可以在EOS Kernel项目inc/rtl.h文件的第113行查看此宏定义的源代码。 按要求应修改为:while (!ListIsEmpty(&Semaphore-WaitListHead)&(ReleaseCount)PspWakeThread(&Semaphore-WaitListHead, STATUS_SUCCESS);PspThreadSchedule();ReleaseCount-;Semaphore-Count = Semaphore-Count + ReleaseCount;/ 可能有线程被唤醒,执行线程调度。Status = STATUS_SUCCESS;KeE

21、nableInterrupts(IntState); / 原子操作完成,恢复中断。return Status;3、 测试方法修改完毕后,可以按照下面的方法进行测试: 1. 使用修改完毕的EOS Kernel项目生成完全版本的SDK文件夹,并覆盖之前的生产者消费者应用程序项目的SDK文件夹。 2. 按F5调试执行原有的生产者消费者应用程序项目,结果必须仍然与图13-2一致。如果有错误,可以调试内核代码来查找错误,然后在内核项目中修改,并重复步骤1。 3. 将Producer函数中等待Empty信号量的代码行 WaitForSingleObject(EmptySemaphoreHandle, IN

22、FINITE);替换为 while(WAIT_TIMEOUT = WaitForSingleObject(EmptySemaphoreHandle, 300) printf(Producer wait for empty semaphore timeoutn); 将Consumer函数中等待Full信号量的代码行 WaitForSingleObject(FullSemaphoreHandle, INFINITE);替换为while(WAIT_TIMEOUT = WaitForSingleObject(FullSemaphoreHandle, 300) printf(Consumer wait

23、for full semaphore timeoutn); 启动调试新的生产者消费者项目,查看在虚拟机中输出的结果,验证信号量超时等待功能是否能够正常执行。如果有错误,可以调试内核代码来查找错误,然后在内核项目中修改,并重复步骤1。 如果超时等待功能已经能够正常执行,可以考虑将消费者线程修改为一次消费两个产品,来测试ReleaseCount参数是否能够正常使用。使用实验文件夹中NewConsumer.c文件中的Consumer函数替换原有的Consumer函数。 三、 实验要求:1、 P143,生产者在生产了13号产品后本来要继续生产14号产品,可此时生产者为什么必须等待消费者消费了4号产品后

24、,才能生产14号产品呢?生产者和消费者是怎样使用同步对象来实现该同步过程的呢?因为缓冲池已满,此时生成了14个产品(013),只消费了4个(03),缓冲池大小为10,因此生产者必须等消费者消费了4号产品后,再生产14号产品。简单地说,在同一地址空间执行2个线程:生产者线程和消费者线程。生产者线程生产产品,放入缓冲池等待消费者消费,消费者线程从缓冲池中获得产品,释放缓冲池。当生产者线程生产物品时,如果缓冲池已满,那么生产者线程必须等待消费者线程释放出一个空缓冲区。当消费者线程消费物品时,如果没有满的缓冲区,那么消费者线程将被阻塞,直到新的物品被生产出来。2、 P145-3.4 修改EOS的信号量

25、算法(只看一次消费1个产品的,一次消费2个产品的可以写到实验报告中)修改方法请参考本实验报告算法部分。下面给出运行截图:修改前:修改后:3、 P147-四、 思考与练习-2. 绘制ps/semaphore.c文件内PsWaitForSemaphore和PsReleaseSemaphore函数的流程图。PsWaitForSemaphore:开始YESINFINITE != MillisecondsNOASSERT(KeGetIntNesting() = 0); IntState = KeEnableInterrupts(FALSE); Semphore-Count-;ASSERT(FALSE);

26、 return STATUS_INVALID_PARAMETER;NOSemphore-Count WaitListHead,INFINITE);KeEnableInterrupts(IntState);return STATUS_SUCCESS;结束PsReleaseSemaphore:开始YESReleaseCount != 1NOASSERT(FALSE); return STATUS_INVALID_PARAMETER;IntState = KeEnableInterrupts(FALSE);YESSemaphore-Count + ReleaseCount Semaphore-Max

27、imumCountNONULL != PreviousCountYESStatus = STATUS_SEMAPHORE_LIMIT_EXCEEDED;*PreviousCount = Semaphore-Count;Semaphore-Count+;YESSemaphore-Count WaitListHead, STATUS_SUCCESS);PspSchedule();Status = STATUS_SUCCESS;KeEnableInterrupts(IntState); return Status;结束四、实验心得 1、了解了EOS 在 PC 机上进程创的过程。 2、查看EOS进程创建的状态和行为,理解进程同步的具体执行方法。 3、对创建进程的函数进行了修改,使得可以查看缓冲池是否满。12

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

copyright@ 2023-2025  zhuangpeitu.com 装配图网版权所有   联系电话:18123376007

备案号:ICP2024067431-1 川公网安备51140202000466号


本站为文档C2C交易模式,即用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知装配图网,我们立即给予删除!