欢迎来到冰点文库! | 帮助中心 分享价值,成长自我!
冰点文库
全部分类
  • 临时分类>
  • IT计算机>
  • 经管营销>
  • 医药卫生>
  • 自然科学>
  • 农林牧渔>
  • 人文社科>
  • 工程科技>
  • PPT模板>
  • 求职职场>
  • 解决方案>
  • 总结汇报>
  • ImageVerifierCode 换一换
    首页 冰点文库 > 资源分类 > DOCX文档下载
    分享到微信 分享到微博 分享到QQ空间

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

    • 资源ID:12107058       资源大小:127.74KB        全文页数:22页
    • 资源格式: DOCX        下载积分:1金币
    快捷下载 游客一键下载
    账号登录下载
    微信登录下载
    三方登录下载: 微信开放平台登录 QQ登录
    二维码
    微信扫一扫登录
    下载资源需要1金币
    邮箱/手机:
    温馨提示:
    快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。
    如填写123,账号就是123,密码也是123。
    支付方式: 支付宝    微信支付   
    验证码:   换一换

    加入VIP,免费下载
     
    账号:
    密码:
    验证码:   换一换
      忘记密码?
        
    友情提示
    2、PDF文件下载后,可能会被浏览器默认打开,此种情况可以点击浏览器菜单,保存网页到桌面,就可以正常下载了。
    3、本站不支持迅雷下载,请使用电脑自带的IE浏览器,或者360浏览器、谷歌浏览器下载即可。
    4、本站资源下载后的文档和图纸-无水印,预览文档经过压缩,下载后原文更清晰。
    5、试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。

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

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

    2、)使用 EOS 的信号量解决生产者消费者问题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 的信号量解决生产者消费者问题在本实验文件夹中

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

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

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

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

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

    8、andle, INFINITE);添加一个断点。3.按F5继续调试,到断点处中断。4.WaitForSi ngleObject函数最终会调用内核中的 PsWaitForSem aphore函数完成等待操作。所以,在semaphore.c文件中 PsWaitForSemaphore函数的第一行(第68行)添加一个 断点。5.按 F5 继续调试,到断点处中断。6.按F10单步调试,直到完成PsWaitForSemaphore函数中的所有操作。可以 看到此次执行并没有进行等待,只是将 Empty 信号量的计数减少了 1(由 10变为了 9)就返回了。3.2.2释放信号量(不唤醒)1.删除所有的断点(

    9、防止有些断点影响后面的调试) 。2.在eosapp.c文件的Producer函数中,释放Full信号量的代码行(第152行)ReleaseSemaphore(FullSemaphoreHandle, 1, NULL);添加一个断点。3.按F5继续调试,到断点处中断。4.按 F11 调试进入 ReleaseSemaphore函数。5.继续按 F11 调试进入 PsReleaseSemaphoreObjec函数。6.先使用 F10 单步调试,当黄色箭头指向第 269行时使用 F11 单步调试,进入 PsReleaseSemaphore函数。7.按F10单步调试,直到完成PsReleaseSemap

    10、hore函数中的所有操作。可以 看到此次执行没有唤醒其它线程(因为此时没有线程在 Full 信号量上被阻塞),只是将 Full 信号量 的计数增加了 1(由 0 变为了 1 )。生产者线程通过等待 Empty 信号量使空缓冲区数量减少了 1,通过释放 Full 信号 量使满缓冲区数量增加了 1,这样就表示生产者线程生产了一个产品并占用了一个缓冲区。3.2.3等待信号量(阻塞)由于开始时生产者线程生产产品的速度较快,而消费者线程消费产品的速度较 慢,所以当缓冲池中所有的缓冲区都被产品占用时, 生产者在生产新的产品时就会被阻塞, 下面调试这 种情况。1.结束之前的调试。2.删除所有的断点。3.按

    11、F5 重新启动调试。 OS Lab 会首先弹出一个调试异常对话框。4.在调试异常对话框中选择“是” ,调试会中断。5.在 semaphore.c文件中的 PsWaitForSemaphore函数的PspWait(&Semaphore-WaitListHead, INFINITE);代码行(第 78 行)添加一个断点。6.按 F5 继续调试,并立即激活虚拟机窗口查看输出。开始时生产者、消费者 都不会被信号量阻塞,同步执行一段时间后才在断点处中断。7.中断后,查看“调用堆栈”窗口,有 Producer 函数对应的堆栈帧,说明此 次调用是从生产者线程函数进入的。8.在“调用堆栈”窗口中双击 Prod

    12、ucer 函数所在的堆栈帧,绿色箭头指向等 待 Empty 信号量的代码行,查看Producer函数中变量i的值为14,表示生产者线程正在尝试生产 14 号产品。9.在“调用堆栈”窗口中双击 PsWaitForSemaphore函数的堆栈帧,查看Empty 信号量计数(Semaphore-Coun)的值为-1,所以会调用 PspWait函数将生产者线程放入 Empty 信号量的等待队列中进行等待(让出 CPU)。10.激活虚拟机窗口查看输出的结果。生产了从 0到13的 14个产品,但是只消 费了从 0 到 3 的 4 个产品,所以缓冲池中的 1 0个缓冲区就都被占用了,这与之前调试的结果是一致

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

    14、.查看 PsReleaseSemaphore函数中 Empty 信号量计数(Semaphore-Coun) 的值为-1,和生产者线程被阻塞时的值是一致的。7.按F10单步调试PsReleaseSemaphor函数,直到在代码行(第 132行) PspWakeThread(&Semaphore-WaitListHead, STATUS_SUCCESS);处中断 。此时 Empty 信 号量 计数 的值已经 由-1 增加 为了 0, 需要调用PspWakeThreac函数唤醒阻塞在 Empty 信号量等待队列中的生产者线程(放入就绪队列中) ,然后调用PspSchedule 函数执行调度,这样生产

    15、者线程就得以继续执行。按照下面的步骤验证生产者线程被唤醒后,是从之前被阻塞时的状态继续执行的:1.在 semaphore.c文件中 PsWaitForSemaphore函数的最后一行(第 83 行) 代码处添加一个断点。2.按F5继续调试,在断点处中断。3.查 看 PsWaitForSemaphore 函 数 中 Empty 信 号 量 计 数( Semaphore-Coun)t 的值为 0,和生产者线 程被唤醒时的值是一致的。4.在“调用堆栈”窗口中可以看到是由Producer函数进入的。激活Producer 函数的堆栈帧,查看Producer函数中变量i的值为14,表明之前被阻塞的、正在尝

    16、试生产 14号产品 的生产者线程已经从PspWait函数返回并继续执行了。5.结束此次调试。4修改EOS勺信号量算法1 )根据文档修改的代码如下:PsWaitForSemaphore 函数代码:STATUSPsWaitForSemaphore(IN PSEMAPHORE Semaphore,IN ULONG Milliseconds)/*+功能描述:信号量的Wait操作(P操作)。参数:Semaphore - Wait 操作的信号量对象。Milliseconds - 等待超时上限,单位毫秒。返回值:STATUS_SUCCE。 SS当你修改信号量使之支持超时唤醒功能后,如果等待超时,应该返回ST

    17、ATUS_TIMEOJJT-*/BOOL IntState;STATUS Status;中断环境下不能调用此函数ASSERT(KeGetIntNesting() = 0); /IntState = KeEnableInterrupts(FALSE); / 开始原子操作,禁止中断。/ 目前仅实现了标准记录型信号量,不支持超时唤醒功能,所以 PspWait 函数/ 的第二个参数的值只能是 INFINITE 。/if (Semaphore-Count 0)Semaphore-Count-;Status = STATUS_SUCCESS;else Status=PspWait(&Semaphore-W

    18、aitListHead, Milliseconds);KeEnableInterrupts(IntState); / 原子操作完成,恢复中断。return Status;PsReleaseSemaphord 码如下:STATUSPsReleaseSemaphore(IN PSEMAPHORE Semaphore,IN LONG ReleaseCount,OUT PLONG PreviousCount)/*+功能描述:信号量的 Signal 操作( V 操作)。参数:Semaphore - Wait 操作的信号量对象。ReleaseCount - 信号量计数增加的数量。当前只能为 1 。当你修改

    19、信号量 使之支持超时唤醒功能后,此参数的值能够大于等于 1 。PreviousCount - 返回信号量计数在增加之前的值。返回值:如果成功释放信号量,返回 STATUS_SUCCESS-*/STATUS Status;BOOL IntState;IntState = KeEnableInterrupts(FALSE); / 开始原子操作,禁止中断。if (Semaphore-Count + ReleaseCount Semaphore-MaximumCount) Status = STATUS_SEMAPHORE_LIMIT_EXCEEDED; else / 记录当前的信号量的值。/if (

    20、NULL != PreviousCount) *PreviousCount = Semaphore-Count;/ 目前仅实现了标准记录型信号量,每执行一次信号量的释放操作/ 只能使信号量的值增加 1 。/for(Semaphore-Count += ReleaseCount;Semaphore-Count0&!ListIsEmpty(&Semaphore-WaitListHead);Semaphore-Count-)PspWakeThread(&Semaphore-WaitListHead, STATUS_SUCCESS);PspThreadSchedule();/Semaphore-Cou

    21、nt+;/*if (Semaphore-Count WaitListHead, STATUS_SUCCESS);*/ 可能有线程被唤醒,执行线程调度。/PspThreadSchedule();Status = STATUS_SUCCESS;KeEnableInterrupts(IntState); / 原子操作完成,恢复中断。return Status;结果如下:2)根据测试要求1将原来的代码更改为如下:/生产者线程函数。/ULONG Producer(PVOID Param)int i;int InIn dex = 0;for (i = 0; i PRODUCT_COUNT; i+) Wai

    22、tForSi ngleObject(EmptySemaphoreHa ndle, INFINITE);WaitForSi ngleObject(MutexHa ndle, INFINITE);printf(Produce a %dn, i);BufferInIndex = i;InIndex = (InIndex + 1) % BUFFER_SIZE;ReleaseMutex(MutexHandle);ReleaseSemaphore(FullSemaphoreHandle, 3, NULL);/ 休息一会。每 500 毫秒生产一个数。/Sleep(500);return 0;/ 消费者线程函

    23、数。/ULONG Consumer(PVOID Param)int i;int OutIndex = 0;for (i = 0; i PRODUCT_COUNT; i+) WaitForSingleObject(FullSemaphoreHandle, INFINITE);WaitForSingleObject(MutexHandle, INFINITE);printf(tttConsume a %dn, BufferOutIndex);OutIndex = (OutIndex + 1) % BUFFER_SIZE;ReleaseMutex(MutexHandle);ReleaseSemaph

    24、ore(EmptySemaphoreHandle, 3, NULL);/ 休息一会儿。让前 10 个数的消费速度比较慢,后面的较快。/if (i 10) Sleep(2000); else Sleep(100);return 0;执行结果如下图所示:05 Tjah PC 一 WirrosrifT Ti mial FC ZHRTCflhSflLE-1 Producer *roduccr Producer Pn Mincer E*roducerEYoducc afPress uait fo? wa it for wo it for unit fop uait for2CCtri+n rn lu s

    25、ullcli cunnle enpiy eemaphore timeout cpply acsnaphorc tificout cpplq scnaphorc tincout mplij Kntirk|ihiii I Inbuilt, enply Eenaphore t ineout ConEaine a 10w I HflllUCunsune d 11Crmsime a 1ZCansune a 13Consunc a 14Cuiisunc a. IllProduce aziCcmsLhe CtmsuncCinisunc CnnsuhfConsiine止1?10灯药E*roducc a22Cu

    26、nsunc 4 21Ciinsun*: nCansunc a Z3ZBProduce a3)将cunsumer的函数替换,测试一次消费两个产品的情况,代码如下/消费者线程函数。/ULONG Consumer(PVOID Param)4)int i;int OutIndex = 0;for (i = 0; i PRODUCT_COUNT; i += 2) while(WAIT_TIMEOUT =WaitForSingleObject(FullSemaphoreHandle, 300)printf(Consumer wait for full semaphore timeoutn);while(W

    27、AIT_TIMEOUT =WaitForSingleObject(FullSemaphoreHandle, 300)printf(Consumer wait for full semaphore timeoutn);WaitForSingleObject(MutexHandle, INFINITE); printf(tttConsume a %dn, BufferOutIndex);OutIndex = (OutIndex + 1) % BUFFER_SIZE;printf(tttConsume a %dn, BufferOutIndex);OutIndex = (OutIndex + 1)

    28、% BUFFER_SIZE;ReleaseMutex(MutexHandle);ReleaseSemaphore(EmptySemaphoreHandle, 2, NULL);/ / 休息一会儿。让前 14 个数的消费速度比较慢,后面的较快。/if (i 14) Sleep(2000); else Sleep(100);return 0;操作结果如下:5.思考题1) PsWaitForSemaphore函数的流程图:PsReleaseSem aphor函数的流程图:th估呂杞賣询16.思考题P143,生产者在生产了 13号产品后本来要继续生产14号产品,可此时生产 者为什么必须等待消费者消费了

    29、 4号产品后,才能生产14号产品呢?生产者和 消费者是怎样使用同步对象来实现该同步过程的呢?答:因为此时生产者生产了 14个产品,而消费者消费了 4个产品,即缓冲区有 10个资源,已经满了,所以只能等待 4号产品消费了才可以继续生产。四实验体会实验过程中遇到的问题主要是在找到需要改的两个函数的过程, 开始始终在app工程中修改sdk代码,导致无论如何编译都不能获得更改的效果,等我一步 步寻找后,最终发现该问题,并成功修改函数,让我对整个进程的创建过程,以 及进程的等待和释放有了更好地了解, 对了大于300ms等待有了较深的理解,并 能够实现同时释放多个资源的效果,对操作系统的流程,有了更深地理解。


    注意事项

    本文(哈尔滨工程大学操作系统实验四进程的同步.docx)为本站会员主动上传,冰点文库仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知冰点文库(点击联系客服),我们立即给予删除!

    温馨提示:如果因为网速或其他原因下载失败请重新下载,重复下载不扣分。




    关于我们 - 网站声明 - 网站地图 - 资源地图 - 友情链接 - 网站客服 - 联系我们

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

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


    收起
    展开