ImageVerifierCode 换一换
格式:DOCX , 页数:19 ,大小:186.17KB ,
资源ID:11695348      下载积分:3 金币
快捷下载
登录下载
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。 如填写123,账号就是123,密码也是123。
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

加入VIP,免费下载
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.bdocx.com/down/11695348.html】到电脑端继续下载(重复下载不扣费)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录   QQ登录  

下载须知

1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。
2: 试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。
3: 文件的所有权益归上传用户所有。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 本站仅提供交流平台,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

版权提示 | 免责声明

本文(操作系统试验进程同步.docx)为本站会员(b****4)主动上传,冰豆网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知冰豆网(发送邮件至service@bdocx.com或直接QQ联系客服),我们立即给予删除!

操作系统试验进程同步.docx

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

2、消费者问题 (3)调试EOS信号量的工作过程 的信号量算法)修改EOS(4二、实验环境 EOS操作系统和OS Lab集成实验环境,主要运用了C语言。 三、实验过程 3. 需要解决的问题及解答 (1)P143,生产者在生产了13号产品后本来要继续生产14号产品,可此时生产者为什么必须等待消费者消费了4号产品后,才能生产14号产品呢?生产者和消费者是怎样使用同步对象来实现该同步过程的呢? 这是因为临界资源的限制。临界资源就像产品仓库,只有“产品仓库”空闲生产者才能生产东西,有权向里面放东西。因此它必须要等到消费者,取走产品,临界资源空闲时,才能继续生产14号产品。 (2)P147-四思考与练习-2

3、. 绘制ps/semaphore.c文件内PsWaitForSemaphore和 函数的流程图。PsReleaseSemaphore函数开始 Semaphore-Count+ReleaseCountSemmaphore-MaxinCount 队函数开始 返回SEMAPHOR LINIT EXCEECED 开始原子操作开始原子操作信号量减一信小于线程进 号量0? 记录当前信号量Status=STAUS 信号量加1 Semaphore-Count= 0 & InitialCount 0); Semaphore-Count = InitialCount; Semaphore-MaximumCount

4、 = MaximumCount; ListInitializeHead(&Semaphore-WaitListHead); STATUS PsWaitForSemaphore(IN PSEMAPHORE Semaphore,IN INT Milliseconds,IN STATUS i ) /*+ 功能描述:信号量的 Wait 操作(P 操作)。 参数:Semaphore - Wait 操作的信号量对象。 Milliseconds - 等待超时上限,单位毫秒。返回值: STATUS_SUCCESS。 -*/ BOOL IntState; ASSERT(KeGetIntNesting() = 0

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

6、; STATUS PsReleaseSemaphore(IN PSEMAPHORE Semaphore,IN LONG ReleaseCount,OUT PLONG PreviousCount) /*+ 功能描述:信号量的 Signal 操作(V 操作)。 参数:Semaphore - Wait 操作的信号量对象。 - 信号量计数增加的数量。当前只能为 1。当你修改信号量使之支持超时唤醒功能后,此参数的值能够大于等于 1。 PreviousCount - 返回信号量计数在增加之前的值。 返回值:如果成功释放信号量,返回 STATUS_SUCCESS。 -*/ STATUS Status; BO

7、OL IntState; IntState = KeEnableInterrupts(FALSE); / 开始原子操作,禁止中断。 if (Semaphore-Count + ReleaseCount Semaphore-MaximumCount) Status = STATUS_SEMAPHORE_LIMIT_EXCEEDED; else if (NULL != PreviousCount) *PreviousCount = Semaphore-Count; INT j=Semaphore-Count; while(!ListIsEmpty(&Semaphore-WaitListHead)&

8、(ReleaseCount) PspWakeThread(&Semaphore-WaitListHead, STATUS_SUCCESS); PspThreadSchedule(); ReleaseCount-; Semaphore-Count=j+ReleaseCount; Status = STATUS_SUCCESS; KeEnableInterrupts(IntState); / 原子操作完成,恢复中断。 return Status; POBJECT_TYPE PspSemaphoreType = NULL;/ 用于初始化 semaphore 结构体的参数结构体。 typedef st

9、ruct _SEM_CREATE_PARAM LONG InitialCount; LONG MaximumCount; SEM_CREATE_PARAM, *PSEM_CREATE_PARAM; / semaphore 对象的构造函数,在创建新 semaphore 对象时被调用。 VOID PspOnCreateSemaphoreObject( IN PVOID SemaphoreObject, IN ULONG_PTR CreateParam ) PsInitializeSemaphore( (PSEMAPHORE)SemaphoreObject, (PSEM_CREATE_PARAM)C

10、reateParam)-InitialCount, (PSEM_CREATE_PARAM)CreateParam)-MaximumCount ); / / semaphore 对象类型的初始化函数。/ VOID PspCreateSemaphoreObjectType(VOID) STATUS Status; OBJECT_TYPE_INITIALIZER Initializer; Initializer.Create = PspOnCreateSemaphoreObject; Initializer.Delete = NULL; Initializer.Wait = (OB_WAIT_MET

11、HOD)PsWaitForSemaphore; Initializer.Read = NULL; Initializer.Write = NULL; Status = ObCreateObjectType(SEMAPHORE, &Initializer, &PspSemaphoreType); if (!EOS_SUCCESS(Status) KeBugCheck(Failed to create semaphore object type!); / / semaphore 对象的构造函数。/ STATUS PsCreateSemaphoreObject( IN LONG InitialCou

12、nt, IN LONG MaximumCount, IN PSTR Name, OUT PHANDLE SemaphoreHandle ) STATUS Status; PVOID SemaphoreObject; SEM_CREATE_PARAM CreateParam; if(InitialCount 0 | MaximumCount MaximumCount) return STATUS_INVALID_PARAMETER; / 创建信号量对象。 CreateParam.InitialCount = InitialCount; CreateParam.MaximumCount = Max

13、imumCount; Status= ObCreateObject( PspSemaphoreType, Name, sizeof(SEMAPHORE), (ULONG_PTR)&CreateParam &SemaphoreObject); return Status; if (!EOS_SUCCESS(Status) Status = ObCreateHandle(SemaphoreObject, SemaphoreHandle); if (!EOS_SUCCESS(Status) ObDerefObject(SemaphoreObject); return Status; / / sema

14、phore 对象的 signal 操作函数。 / STATUS PsReleaseSemaphoreObject(IN HANDLE Handle,IN LONG ReleaseCount,IN PLONG PreviousCount) STATUS Status; PSEMAPHORE Semaphore; if (ReleaseCount 1) return STATUS_INVALID_PARAMETER; / 由 semaphore 句柄得到 semaphore 对象的指针。 Status = ObRefObjectByHandle(Handle, PspSemaphoreType,

15、(PVOID*)&Semaphore); if (EOS_SUCCESS(Status) Status = PsReleaseSemaphore(Semaphore, ReleaseCount, PreviousCount); ObDerefObject(Semaphore); return Status; #include EOSApp.h 缓冲池。/ 10 #define BUFFER_SIZE int BufferBUFFER_SIZE; / 产品数量。 #define PRODUCT_COUNT 30 / 用于生产者和消费者同步的对象句柄。 HANDLE MutexHandle; HA

16、NDLE EmptySemaphoreHandle; HANDLE FullSemaphoreHandle; / 生产者和消费者的线程函数 ULONG Producer(PVOID Param); ULONG Consumer(PVOID Param); / main 函数参数的意义: / argc - argv 数组的长度,大小至少为 1,argc - 1 为命令行参数的数量。 / argv - 字符串指针数组,数组长度为命令行参数个数 + 1。其中 argv0 固定指向当前进程所执行的可执行文件的路径 /符串,argv1 及其后面的指针指向各个命令行参数。 int main(int arg

17、c, char* argv) HANDLE ProducerHandle; HANDLE ConsumerHandle; #ifdef _DEBUG _asm(int $3n nop); #endif / 创建用于互斥访问缓冲池的 Mutex 对象。 MutexHandle = CreateMutex(FALSE, NULL); if (NULL = MutexHandle) return 1; / 创建 Empty 信号量,表示缓冲池中空缓冲区数量。初始计数和最大计数都为 BUFFER_SIZE。 EmptySemaphoreHandle = CreateSemaphore(BUFFER_S

18、IZE, BUFFER_SIZE, NULL); if (NULL = EmptySemaphoreHandle) return 2; / 创建 Full 信号量,表示缓冲池中满缓冲区数量。初始计数为 0,最大计数为 BUFFER_SIZE。 FullSemaphoreHandle = CreateSemaphore(0, BUFFER_SIZE, NULL); if (NULL = FullSemaphoreHandle) return 3; / 创建生产者线程。 ProducerHandle = CreateThread( 0, / 默认堆栈大小 Producer, / 线程函数入口地址

19、NULL, / 线程函数参数 / 创建标志 0, / 线程 ID NULL ); if (NULL = ProducerHandle) return 4; / 创建消费者线程。 ConsumerHandle = CreateThread( 0,Consumer,NULL,0,NULL ); if (NULL = ConsumerHandle) return 5; / 等待生产者线程和消费者线程结束。 WaitForSingleObject(ProducerHandle, INFINITE); WaitForSingleObject(ConsumerHandle, INFINITE); / 关闭

20、句柄 CloseHandle(MutexHandle); CloseHandle(EmptySemaphoreHandle); CloseHandle(FullSemaphoreHandle); CloseHandle(ProducerHandle); CloseHandle(ConsumerHandle); return 0; / 生产者线程函数。 ULONG Producer(PVOID Param) int i; int InIndex = 0; for (i = 0; i PRODUCT_COUNT; i+) while(WAIT_TIMEOUT = WaitForSingleObje

21、ct(EmptySemaphoreHandle, 300) printf(Producer wait for empty semaphore timeoutn); WaitForSingleObject(MutexHandle, INFINITE); printf(Produce a %dn, i); BufferInIndex = i; InIndex = (InIndex + 1) % BUFFER_SIZE; ReleaseMutex(MutexHandle); ReleaseSemaphore(FullSemaphoreHandle, 1, NULL); / 休息一会。每 500 毫秒

22、生产一个数。 Sleep(500); return 0; / 消费者线程函数。 ULONG Consumer(PVOID Param) int i; int OutIndex = 0; for (i = 0; i PRODUCT_COUNT; i+) while(WAIT_TIMEOUT = WaitForSingleObject(FullSemaphoreHandle, 300) printf(Consumer wait for full semaphore timeoutn); WaitForSingleObject(MutexHandle, INFINITE); printf( ttCo

23、nsume a %dn, BufferOutIndex); OutIndex = (OutIndex + 1) % BUFFER_SIZE; ReleaseMutex(MutexHandle); ReleaseSemaphore(EmptySemaphoreHandle, 1, NULL); / 休息一会儿。让前 10 个数的消费速度比较慢,后面的较快。 return 0; if (i 10) Sleep(2000); else Sleep(100); 6. 程序运行时的初值和运行结果 3.1 准备实验 1. 启动OS Lab。 2. 新建一个EOS Kernel项目。 3. 生成EOS Ke

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

25、S信号量的工作过程 3.3.1 创建信号量 会首先弹出一个调试异常对话框。OS Lab应用项目。EOS启动调试F5按1. 2. 在调试异常对话框中选择“是”,调试会中断。 3. 在main函数中创建Empty信号量的代码行,第77行添加一个断点。 4. 按F5继续调试,到此断点处中断。 5. 按F11调试进入CreateSemaphore函数。可以看到此API函数只是调用了EOS内核中的PsCreateSemaphoreObject函数来创建信号量对象。 6. 按F11调试进入semaphore.c文件中的PsCreateSemaphoreObject函数。在此函数中,会在EOS内核管理的内存

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

27、调用堆栈”窗口,查看函数的调用层次。 3.3.2 等待、释放信号量 3.3.2.1 等待信号量(不阻塞) 1.删除所有的断点(防止有些断点影响后面的调试)。 2.在eosapp.c文件的Producer函数中,等待Empty信号量的代码行(第144行)添加一个断点。 3.按F5继续调试,到断点处中断。 4.WaitForSingleObject 函数最终会调用内核中的PsWaitForSemaphore函数完成等待操作。所以,在semaphore.c文件中PsWaitForSemaphore函数的第一行(第68行)添加一个断点。 5. 按F5继续调试,到断点处中断。 6. 按F10单步调试,直到完成PsWaitForSemaphore函数中的所有操作。可以看到此次执行并没有进行等待,只是将Empty信号量的计数减少了1(由10变为了9)就返回了。 3.3.2.2 释放信号量(不唤醒) 1. 删除所有的断点(防止有些断点影响后面的调试)。 2. 在eosapp.c文件的Producer函数中,释放Full信号量的代码行(第152行)添加一个断点。 3. 按F5继续调试,到断点处中断。 4. 按F11调试进入ReleaseSemaphore函数。 5. 继续按F11调试进入PsReleaseSema

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1