1、姓名颜凡腾专业软件工程学生所在学院软件学院指导教师曹雪实验室名称地点21b哈尔滨工程大学一、实验概述1. 实验名称 进程的同步2. 实验目的使用 EOS 的信号量, 编程解决生产者消费者问题,理解进程同步的意义。调试跟踪 EOS 信号量的工作过程,理解进程同步的原理。修改 EOS 的信号量算法,使之支持等待超时唤醒功能(有限等待),加深理解进程同步的原理。3. 实验类型设计二、实验环境OS Lab三、实验过程使用EOS的信号量解决生产者消费者问题:立即激活虚拟机窗口查看生产者消费者同步执行的过程调试EOS信号量的工作过程:创建信号量按 F5 继续调试,到断点处中断。观察 PsInitializ
2、eSemaphore 函数中用来初始化信号量结构体成员的值,应该和传入 CreateSemaphore 函数的参数值是一致的按 F10 单步调试 PsInitializeSemaphore 函数执行的过程,查看信号量结构体被初始化的过程。打开“调用堆栈”窗口,查看函数的调用层次。等待、释放信号量:等待信号量(不阻塞)按 F10 单步调试,直到完成 PsWaitForSemaphore 函数中的所有操作。可以看到此次执行并没有进行等待,只是将 Empty 信号量的计数减少了 1(由 10 变为了 9)就返回了。释放信号量(不换醒)按 F10 单步调试,直到完成 PsReleaseSemaphor
3、e 函数中的所有操作。可以看到此次执行没有唤醒其它线程(因为此时没有线程在 Full 信号量上被阻塞),只是将 Full 信号量的计数增加了 1(由 0 变为了 1)。等待信号量(阻塞) 由于开始时生产者线程生产产品的速度较快,而消费者线程消费产品的速度较慢,所以当缓冲池中所有的缓冲区都被产品占用时,生产者在生产新的产品时就会被阻塞.在“调用堆栈”窗口中双击 Producer 函数所在的堆栈帧,绿色箭头指向等待 Empty 信号量的代码行,查看 Producer 函数中变量 i 的值为 14,表示生产者线程正在尝试生产 14 号产品。在“调用堆栈”窗口中双击 PsWaitForSemaphor
4、e 函数的堆栈帧,查看 Empty 信号量计数( Semaphore-Count)的值为-1,所以会调用 PspWait 函数将生产者线程放入 Empty 信号量的等待队列中进行等待(让出 CPU)。激活虚拟机窗口查看输出的结果。生产了从 0 到 13 的 14 个产品,但是只消费了从 0 到 13 的14 个产品,所以缓冲池中的 10 个缓冲区就都被占用了,这与之前调试的结果是一致的。释放信号量(唤醒)只有当消费者线程从缓冲池中消费了一个产品,从而产生一个空缓冲区后,生产者线程才会被唤醒并继续生产 14 号产品。查看 Consumer 函数中变量 i 的值为 4。查看 PsReleaseSe
5、maphore 函数中 Empty 信号量计数( Semaphore-Count)的值为-1,和生产者线程被阻塞时的值是一致的。按 F10 单步调试 PsReleaseSemaphore 函数,直到在代码行(第 132 行)PspWakeThread(&Semaphore-WaitListHead, STATUS_SUCCESS)处中断。此时 Empty 信号量计数的值已经由-1 增加为了 0,需要调用 PspWakeThread 函数唤醒阻塞在 Empty 信号量等待队列中的生产者线程(放入就绪队列中),然后调用 PspSchedule 函数执行调度,这样生产者线程就得以继续执行。查看 Ps
6、WaitForSemaphore 函数中 Empty 信号量计数( Semaphore-Count)的值为 0,和生产者线程被唤醒时的值是一致的。在“调用堆栈”窗口中可以看到是由 Producer 函数进入的。 激活 Producer 函数的堆栈帧,查看Producer 函数中变量 i 的值为 14,表明之前被阻塞的、正在尝试生产 14 号产品的生产者线程已经从 PspWait 函数返回并继续执行了。修改EOS的信号量算法在目前 EOS Kernel 项目的 ps/semaphore.c 文件中, PsWaitForSemaphore 函数的 Milliseconds 参数只能是 INFINI
7、TE, PsReleaseSemaphore 函数的 ReleaseCount 参数只能是 1 。现在要求同时修改PsWaitForSemaphore 函数和 PsReleaseSemaphore 函数中的代码,使这两个参数能够真正起到作用,使信号量对象支持等待超时唤醒功能和批量释放功能。修改 PsWaitForSemaphore 函数:修改 PsReleaseSemaphore 函数测试:按 F5 调试执行原有的生产者消费者应用程序项目,其结果如下所示将 Producer 函数中等待 Empty 信号量的代码行WaitForSingleObject(EmptySemaphoreHandle,
8、 INFINITE);替换为while(WAIT_TIMEOUT = WaitForSingleObject(EmptySemaphoreHandle, 300)printf(Producer wait for empty semaphore timeoutn);将 Consumer 函数中等待 Full 信号量的代码行WaitForSingleObject(FullSemaphoreHandle, INFINITE);替换为while(WAIT_TIMEOUT = WaitForSingleObject(FullSemaphoreHandle, 300)Consumer wait for f
9、ull semaphore timeoutn启动调试新的生产者消费者项目,查看在虚拟机中输出的结果,验证信号量超时等待功能是否能够正常执行。将消费者线程修改为一次消费两个产品,来测试ReleaseCount 参数是否能够正常使用。四、思考题1、思考在 ps/semaphore.c 文件内的 PsWaitForSemaphore 和PsReleaseSemaphore 函数中,为什么要使用原子操作?可以参考本书第 2 章中的第 2.6 节。答:当在执行PsWaitForSemaphore和PsReleaseSemaphore函数的时候,是不允许cpu响应外部中断的,如果此时cpu响应了外部中断,
10、就会产生不可预料的结果,无法正常完成函数的功能。2、绘制 ps/semaphore.c 文件内 PsWaitForSemaphore 和 PsReleaseSemaphore 函数的流程图。PsWaitForSemaphore流程图: PsReleaseSemaphore函数的流程图:3、生产者线程和消费者线程是如何使用Mutex、Empty信号量和 Full信号量来实现同步的?在两个线程函数中对这三个同步对象的操作能够改变顺序吗?Mutex、Empty、Full三个信号量的初始值分别为1、10、0,当出现一个生产者线程访问缓冲池时,首先Empty要减1,如果大于0,就说明还有剩余的缓冲区可以
11、让生产者放入产品,小于等于0则生产者线程进入等待队列;再对Mutex减1,如果大于等于0,就说明没有线程占用着缓冲池,小于0则生产者线程进入等待队列。生产完产品后,对Mutex值加1,解除封锁;再对Full值加1,说明生产了一个产品占用了一个缓冲区。消费者线程也是这样的,对信号量的操作顺序与生产者线程是相反。不能对这三个同步对象的操作改变顺序,否则可能造成死锁。4、生产者在生产了13号产品后本来要继续生产14号产品,可此时生产者为什么必须等待消费者消费了4号产品后,才能生产14号产品呢?生产者和消费者是怎样使用同步对象来实现该同步过程的呢?因为临界资源的访问是受限制的,程序中限定了缓冲池的大小
12、值为10,只有缓冲池空余时生产者才能向里边放产品,同时只有缓冲池有产品的时候消费者才能向外取东西。当生产者生产了13号产品后,共生产了从0到13的14个产品,但是只取走了从0到3的4个产品,所以缓冲池中的10个缓冲区就都被占用了,所以不能继续生产14号产品,而要等到消费者消费掉一个产品后,缓冲池有空余位置,才能继续生产14号产品。当生产者线程生产了13号产品以后,这时候Full信号量的值为10,而Empty信号量的值为0,此时若生产者线程要再生产一个产品,先对Empty减1,此时Empty值小于零,生产者线程进入等待队列;而此时若有一个消费者线程要消费一个产品,先对Full减1,此时Full值
13、为9,大于0,如果没有线程占用缓冲池,消费者可以消费一个产品。这样,生产者和消费者就能实现同步过程了。五、实验体会通过本次实验,我对EOS操作系统的P、V操作的调试,以及对源码的阅读,有了一个更加深入的理解,学会了一个真正运行的操作系统中是如何通过信号量以及P、V操作来解决进程同步问题的。我在这次实验中遇到的难点是修改PsReleaseSemaphore 函数使其能批量释放,虽然实验材料中给出了一个解决方案,但是当我直接按实验材料中的方案走时,运行编写的程序后始终不能达到预期的效果。后来我经过深入的思考同时又重新捋了一遍生产者和消费者的同步过程,最后经过重新编写程序,这才成功实现了目标。反过头再看自己编写写的程序,其实与实验材料上的方案本质上是一致的,所以通过这次实验,我明白了其实只要是理解到了问题的原理,自己完全有能力解决问题。(范文素材和资料部分来自网络,供参考。可复制、编制,期待你的好评与关注)
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1