操作系统实验五Word文档格式.docx

上传人:b****2 文档编号:5254014 上传时间:2023-05-04 格式:DOCX 页数:20 大小:1.66MB
下载 相关 举报
操作系统实验五Word文档格式.docx_第1页
第1页 / 共20页
操作系统实验五Word文档格式.docx_第2页
第2页 / 共20页
操作系统实验五Word文档格式.docx_第3页
第3页 / 共20页
操作系统实验五Word文档格式.docx_第4页
第4页 / 共20页
操作系统实验五Word文档格式.docx_第5页
第5页 / 共20页
操作系统实验五Word文档格式.docx_第6页
第6页 / 共20页
操作系统实验五Word文档格式.docx_第7页
第7页 / 共20页
操作系统实验五Word文档格式.docx_第8页
第8页 / 共20页
操作系统实验五Word文档格式.docx_第9页
第9页 / 共20页
操作系统实验五Word文档格式.docx_第10页
第10页 / 共20页
操作系统实验五Word文档格式.docx_第11页
第11页 / 共20页
操作系统实验五Word文档格式.docx_第12页
第12页 / 共20页
操作系统实验五Word文档格式.docx_第13页
第13页 / 共20页
操作系统实验五Word文档格式.docx_第14页
第14页 / 共20页
操作系统实验五Word文档格式.docx_第15页
第15页 / 共20页
操作系统实验五Word文档格式.docx_第16页
第16页 / 共20页
操作系统实验五Word文档格式.docx_第17页
第17页 / 共20页
操作系统实验五Word文档格式.docx_第18页
第18页 / 共20页
操作系统实验五Word文档格式.docx_第19页
第19页 / 共20页
操作系统实验五Word文档格式.docx_第20页
第20页 / 共20页
亲,该文档总共20页,全部预览完了,如果喜欢就下载吧!
下载资源
资源描述

操作系统实验五Word文档格式.docx

《操作系统实验五Word文档格式.docx》由会员分享,可在线阅读,更多相关《操作系统实验五Word文档格式.docx(20页珍藏版)》请在冰点文库上搜索。

操作系统实验五Word文档格式.docx

 

哈尔滨工程大学

一、实验概述

1.实验名称

进程的同步

2.实验目的

1.使用EOS的信号量,编程解决生产者—消费者问题,理解进程同步的意义。

2.调试跟踪EOS信号量的工作过程,理解进程同步的原理。

3.修改EOS的信号量算法,使之支持等待超时唤醒功能(有限等待),加深理解进程同步的原理。

3.实验类型

验证

二、实验环境

OSLab

三、实验过程

3.1准备实验

按照下面的步骤准备本次实验:

1.启动OSLab。

2.新建一个EOSKernel项目。

3.生成EOSKernel项目,从而在该项目文件夹中生成SDK文件夹。

4.新建一个EOS应用程序项目。

5.使用在第3步生成的SDK文件夹覆盖EOS应用程序项目文件夹中的SDK文件夹。

EmptySemaphoreHandle=CreateSemaphore(BUFFER_SIZE,BUFFER_SIZE,NULL);

添加一个断点。

4.按F5继续调试,到此断点处中断。

5.按F11调试进入CreateSemaphore函数。

可以看到此API函数只是调用了EOS内核中的PsCreateSemaphoreObject函数来创建信号量对象。

6.按F11调试进入semaphore.c文件中的PsCreateSemaphoreObject函数。

在此函数中,会在EOS内核管理的内存中创建一个信号量对象(分配一块内存),而初始化信号量对象中各个成员的操作是在PsInitializeSemaphore函数中完成的。

7.在semaphore.c文件的顶部查找到PsInitializeSemaphore函数的定义(第19行),在此函数的第一行(第39行)代码处添加一个断点。

8.按F5继续调试,到断点处中断。

观察PsInitializeSemaphore函数中用来初始化信号量结构体成员的值,应该和传入CreateSemaphore函数的参数值是一致的。

9.按F10单步调试PsInitializeSemaphore函数执行的过程,查看信号量结构体被初始化的过程。

打开"

调用堆栈"

窗口,查看函数的调用层次。

3.3.2等待、释放信号量

3.3.2.1等待信号量(不阻塞)

生产者和消费者刚开始执行时,用来放产品的缓冲区都是空的,所以生产者在第一次调用WaitForSingleObject函数等待Empty信号量时,应该不需要阻塞就可以立即返回。

按照下面的步骤调试:

1.删除所有的断点(防止有些断点影响后面的调试)。

2.在eosapp.c文件的Producer函数中,等待Empty信号量的代码行(144)WaitForSingleObject(EmptySemaphoreHandle,INFINITE);

3.按F5继续调试,到断点处中断。

4.WaitForSingleObject函数最终会调用内核中的PsWaitForSemaphore函数完成等待操作。

所以,在semaphore.c文件中PsWaitForSemaphore函数的第一行(第68行)添加一个断点。

5.按F5继续调试,到断点处中断。

6.按F10单步调试,直到完成PsWaitForSemaphore函数中的所有操作。

可以看到此次执行并没有进行等待,只是将Empty信号量的计数减少了1(由10变为了9)就返回了。

如图所示,empty的初始值为10。

在完成PsWaitForSemaphore函数中的所有操作后empty的值变成了9。

3.3.2.2释放信号量(不唤醒)

2.在eosapp.c文件的Producer函数中,释放Full信号量的代码行(第152行)ReleaseSemaphore(FullSemaphoreHandle,1,NULL);

4.按F11调试进入ReleaseSemaphore函数。

5.继续按F11调试进入PsReleaseSemaphoreObject函数。

6.先使用F10单步调试,当黄色箭头指向第269行时使用F11单步调试,进入PsReleaseSemaphore函数。

7.按F10单步调试,直到完成PsReleaseSemaphore函数中的所有操作。

可以看到此次执行没有唤醒其它线程(因为此时没有线程在Full信号量上被阻塞),只是将Full信号量的计数增加了1(由0变为了1)。

full信号量初始值为0

full信号量由0变为1

生产者线程通过等待Empty信号量使空缓冲区数量减少了1,通过释放Full信号量使满缓冲区数量增加了1,这样就表示生产者线程生产了一个产品并占用了一个缓冲区。

3.3.2.3等待信号量(阻塞)

由于开始时生产者线程生产产品的速度较快,而消费者线程消费产品的速度较慢,所以当缓冲池中所有的缓冲区都被产品占用时,生产者在生产新的产品时就会被阻塞,下面调试这种情况。

1.结束之前的调试。

2.删除所有的断点。

3.按F5重新启动调试。

OSLab会首先弹出一个调试异常对话框。

4.在调试异常对话框中选择“是”,调试会中断。

5.在semaphore.c文件中的PsWaitForSemaphore函数的PspWait(&

Semaphore->

WaitListHead,INFINITE);

代码行(第78行)添加一个断点。

6.按F5继续调试,并立即激活虚拟机窗口查看输出。

开始时生产者、消费者都不会被信号量阻塞,同步执行一段时间后才在断点处中断。

7.中断后,查看“调用堆栈”窗口,有Producer函数对应的堆栈帧,说明此次调用是从生产者线程函数进入的。

8.在“调用堆栈”窗口中双击Producer函数所在的堆栈帧,绿色箭头指向等待Empty信号量的代码行,查看Producer函数中变量i的值为14,表示生产者线程正在尝试生产14号产品。

9.在“调用堆栈”窗口中双击PsWaitForSemaphore函数的堆栈帧,查看Empty信号量计数(Semaphore->

Count)的值为-1,所以会调用PspWait函数将生产者线程放入Empty信号量的等待队列中进行等待(让出CPU)。

10.激活虚拟机窗口查看输出的结果。

生产了从0到13的14个产品,但是只消费了从0到3的4个产品,所以缓冲池中的10个缓冲区就都被占用了,这与之前调试的结果是一致的。

3.3.2.4释放信号量(唤醒)

只有当消费者线程从缓冲池中消费了一个产品,从而产生一个空缓冲区后,生产者线程才会被唤醒并继续生产14号产品。

可以按照下面的步骤调试:

1.删除所有断点。

2.在eosapp.c文件的Consumer函数中,释放Empty信号量的代码行(第180)ReleaseSemaphor

e(EmptySemaphoreHandle,1,NULL);

4.查看Consumer函数中变量i的值为4,说明已经消费了4号产品。

5.按照3.3.2.2中的方法使用F10和F11调试进入PsReleaseSemaphore函数。

6.查看PsReleaseSemaphore函数中Empty信号量计数(Semaphore->

Count)的值为-1,和生产者线程被阻塞时的值是一致的。

7.按F10单步调试PsReleaseSemaphore函数,直到在代码行(第132行)PspWakeThread(&

WaitListHead,STATUS_SUCCESS);

处中断。

此时Empty信号量计数的值已经由-1增加为了0,需要调用PspWakeThread函数唤醒阻塞在Empty信号量等待队列中的生产者线程(放入就绪队列中),然后调用PspSchedule函数执行调度,这样生产者线程就得以继续执行。

按照下面的步骤验证生产者线程被唤醒后,是从之前被阻塞时的状态继续执行的:

1.在semaphore.c文件中PsWaitForSemaphore函数的最后一行(第83行)代码处添加一个断点。

2.按F5继续调试,在断点处中断。

3.查看PsWaitForSemaphore函数中Empty信号量计数(Semaphore->

Count)的值为0,和生产者线程被唤醒时的值是一致的。

4.在“调用堆栈”窗口中可以看到是由Producer函数进入的。

激活Producer函数的堆栈帧,查看Producer函数中变量i的值为14,表明之前被阻塞的、正在尝试生产14号产品的生产者线程已经从PspWait函数返回并继续执行了。

5.结束此次调试。

3.4修改EOS的信号量算法

修改处代码

运行成功

3.4.3测试方法

修改完毕后,可以按照下面的方法进行测试:

1.使用修改完毕的EOSKernel项目生成完全版本的SDK文件夹,并覆盖之前的生产者-消费者应用程序项目的SDK文件夹。

2.按F5调试执行原有的生产者-消费者应用程序项目,结果必须仍然与图13-2一致。

如果有错误,可以调试内核代码来查找错误,然后在内核项目中修改,并重复步骤1。

3.将Producer函数中等待Empty信号量的代码行WaitForSingleObject(EmptySemaphoreHandle,INFINITE);

替换为while(WAIT_TIMEOUT==WaitForSingleObject(EmptySemaphoreHandle,300)){printf("

Producerwaitforemptysemaphoretimeout\n"

);

}

4.将Consumer函数中等待Full信号量的代码行WaitForSingleObject(FullSemaphoreHandle,INFINITE);

替换为while(WAIT_TIMEOUT==WaitForSingleObject(FullSemaphoreHandle,300)){printf("

Consumerwaitforfullsemaphoretimeout\n"

5.启动调试新的生产者-消费者项目,查看在虚拟机中输出的结果,验证信号量超时等待功能是否能够正常执行。

6.如果超时等待功能已经能够正常执行,可以考虑将消费者线程修改为一次消费两个产品,来测试ReleaseCount参数是否能够正常使用。

使用实验文件夹中NewConsumer.c文件中的Consumer函数替换原有的Consumer函数。

四、思考题

1.思考在ps/semaphore.c文件内的PsWaitForSemaphore和PsReleaseSemaphore函数中,为什么要使用原子操作?

可以参考本书第2章中的第2.6节。

答:

等待和释放操作都是原语操作,在执行等待信号量和释放信号量的时候,不能被打断,所以cpu是不允许响应外部中断的,如果此时cpu响应了外部中断,中间的某些共用的变量会产生不可预料的变化,无法正常完正常的操作。

2.绘制ps/semaphore.c文件内PsWaitForSemaphore和PsReleaseSemaphore函数的流程图。

(1)PsWaitForSemaphore

(2)PsReleaseSemaphore

3.根据本实验3.3.2节中设置断点和调试的方法,练习调试消费者线程在消费第一个产品时,等待Full信号量和释放Empty信号量的过程。

注意信号量计数是如何变化的。

4.根据本实验3.3.2节中设置断点和调试的方法,自己设计一个类似的调试方案来验证消费者线程在消费24号产品时会被阻塞,直到生产者线程生产了24号产品后,消费者线程才被唤醒并继续执行的过程。

提示,可以按照下面的步骤进行调试:

(1)删除所有的断点。

(2)按F5启动调试。

(3)在调试异常对话框中选择“是”,调试会中断。

(4)在Consumer函数中等待Full信号量的代码行(第173行)WaitForSingleObject(FullSemaphoreHandle,INFINITE);

(5)在“断点”窗口(按Alt+F9打开)中此断点的名称上点击右键。

(6)在弹出的快捷菜单中选择“条件”。

(7)在“断点条件”对话框(按F1获得帮助)的表达式编辑框中,输入表达式“i==24”。

(8)点击“断点条件”对话框中的“确定”按钮。

(9)按F5继续调试。

只有当消费者线程尝试消费24号产品时才会在该条件断点处中断。

五、实验体会

本次实验我学会了使用EOS的信号量,编程解决生产者—消费者问题,理解了进程同步的意义。

并且修改EOS的信号量算法,使之支持等待超时唤醒功能(有限等待),加深理解进程同步的原理。

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 初中教育 > 语文

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2