操作系统实验五

  • 格式:doc
  • 大小:1.34 MB
  • 文档页数:22

操作系统实验报告哈尔滨工程大学计算机科学与技术学院第五讲进程的同步一、实验概述1. 实验名称进程的同步2. 实验目的● 使用EOS的信号量,编程解决生产者 消费者问题,理解进程同步的意义。

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

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

3. 实验类型验证,设计4. 实验内容4.1 准备实验4.2 使用EOS的信号量解决生产者-消费者问题4.3 调试EOS信号量的工作过程4.3.1 创建信号量4.3.2 等待、释放信号量4.3.2.1 等待信号量(不阻塞)4.3.2.2 释放信号量(不唤醒)4.3.2.3 等待信号量(阻塞)4.3.2.4 释放信号量(唤醒)4.4 修改EOS的信号量算法二、实验环境操作系统集成实验环境OS LabEOS 操作系统三、实验过程1. 设计思路和流程图2. 需要解决的问题及解答(1). P143生产者在生产了13号产品后本来要继续生产14号产品,可此时生产者为什么必须等待消费者消费了4号产品后,才能生产14号产品呢?生产者和消费者是怎样使用同步对象来实现该同步过程的呢?答:此时生产了0-13号14个产品,消费了0-3号4个产品,缓冲区都占满了。

只有缓冲区有空闲生产者才能生产东西,有权向里面放东西。

所以它必须等到消费者,取走产品,有空闲缓冲区时,才继续生产14号产品。

(2). P145-3.4 修改EOS的信号量算法(只看一次消费1个产品的,一次消费2个产品的可以写到实验报告中)答:见之后部分(3). 思考在ps/semaphore.c文件内的PsWaitForSemaphore和PsReleaseSemaphore函数中,为什么要使用原子操作?答:原子操作要求一旦开始就要运行到结束,不能有中断。

在执行等待信号量和释放信号量的时候,不允许cpu响应外部中断,所以使用原子操作。

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

PsWaitForSemaphore原子操作前关中断开始原子操作P操作NWait操作的信号Y执行P操作Ps Release Semaphore3. 主要数据结构、实现代码及其说明ps/semaphore.c文件#include "psp.h"VOIDPsInitializeSemaphore(IN PSEMAPHORE Semaphore,IN LONG InitialCount,IN LONG MaximumCount)/*++功能描述:初始化信号量结构体。

参数:Semaphore -- 要初始化的信号量结构体指针。

InitialCount -- 信号量的初始值,不能小于0 且不能大于MaximumCount。

MaximumCount -- 信号量的最大值,必须大于0。

返回值:无。

--*/{ASSERT(InitialCount >= 0 && InitialCount <= MaximumCount && MaximumCount > 0); Semaphore->Count = InitialCount;Semaphore->MaximumCount = MaximumCount;ListInitializeHead(&Semaphore->WaitListHead);}STATUSPsWaitForSemaphore(IN PSEMAPHORE Semaphore,IN ULONG Milliseconds)/*++功能描述:信号量的Wait 操作(P 操作)。

参数:Semaphore -- Wait 操作的信号量对象。

Milliseconds -- 等待超时上限,单位毫秒。

返回值:STATUS_SUCCESS。

当你修改信号量使之支持超时唤醒功能后,如果等待超时,应该返回STATUS_TIMEOUT。

--*/{BOOL IntState;STATUS flag;ASSERT(KeGetIntNesting() == 0); // 中断环境下不能调用此函数。

IntState = KeEnableInterrupts(FALSE); // 开始原子操作,禁止中断。

// 目前仅实现了标准记录型信号量,不支持超时唤醒功能,所以PspWait 函数 // 的第二个参数的值只能是INFINITE。

if (Semaphore->Count>0){Semaphore->Count--;flag=STATUS_SUCCESS;}elseflag=PspWait(&Semaphore->WaitListHead, Milliseconds); KeEnableInterrupts(IntState); // 原子操作完成,恢复中断。

return flag;}STATUSPsReleaseSemaphore(IN PSEMAPHORE Semaphore,IN LONG ReleaseCount,OUT PLONG PreviousCount){STATUS Status;BOOL IntState;IntState = KeEnableInterrupts(FALSE); // 开始原子操作,禁止中断。

if (Semaphore->Count + ReleaseCount > Semaphore->MaximumCount) {Status = STA TUS_SEMAPHORE_LIMIT_EXCEEDED;} else {// 记录当前的信号量的值。

if (NULL != PreviousCount) {*PreviousCount = Semaphore->Count;}int mm=Semaphore->Count;// 目前仅实现了标准记录型信号量,每执行一次信号量的释放操作// 只能使信号量的值增加1。

while ((!ListIsEmpty(&Semaphore->WaitListHead))&&(ReleaseCount)){PspWakeThread(&Semaphore->WaitListHead, STA TUS_SUCCESS);PspThreadSchedule();ReleaseCount--;}Semaphore->Count=mm+ReleaseCount;// 可能有线程被唤醒,执行线程调度。

Status = STA TUS_SUCCESS;}KeEnableInterrupts(IntState); // 原子操作完成,恢复中断。

return Status;}POBJECT_TYPE PspSemaphoreType = NULL;// 用于初始化semaphore 结构体的参数结构体。

typedef struct _SEM_CREA TE_PARAM{LONG InitialCount;LONG MaximumCount;}SEM_CREATE_PARAM, *PSEM_CREA TE_PARAM;//semaphore 对象的构造函数,在创建新semaphore 对象时被调用。

VOIDPspOnCreateSemaphoreObject(IN PVOID SemaphoreObject,IN ULONG_PTR CreateParam){PsInitializeSemaphore( (PSEMAPHORE)SemaphoreObject,((PSEM_CREA TE_PARAM)CreateParam)->InitialCount,((PSEM_CREA TE_PARAM)CreateParam)->MaximumCount );}// semaphore 对象类型的初始化函数。

VOIDPspCreateSemaphoreObjectType(VOID){STATUS Status;OBJECT_TYPE_INITIALIZER Initializer;Initializer.Create = PspOnCreateSemaphoreObject;Initializer.Delete = NULL;Initializer.Wait = (OB_WAIT_METHOD)PsWaitForSemaphore;Initializer.Read = NULL;Initializer.Write = NULL;Status = ObCreateObjectType("SEMAPHORE", &Initializer, &PspSemaphoreType); if (!EOS_SUCCESS(Status)) {KeBugCheck("Failed to create semaphore object type!");}}// semaphore 对象的构造函数。

STATUSPsCreateSemaphoreObject(IN LONG InitialCount,IN LONG MaximumCount,IN PSTR Name,OUT PHANDLE SemaphoreHandle){STATUS Status;PVOID SemaphoreObject;SEM_CREA TE_PARAM CreateParam;if(InitialCount < 0 || MaximumCount <= 0 || InitialCount > MaximumCount){ return STA TUS_INV ALID_PARAMETER;}// 创建信号量对象。

CreateParam.InitialCount = InitialCount;CreateParam.MaximumCount = MaximumCount;Status = ObCreateObject( PspSemaphoreType,Name,sizeof(SEMAPHORE),(ULONG_PTR)&CreateParam,&SemaphoreObject);if (!EOS_SUCCESS(Status)) {return Status;}Status = ObCreateHandle(SemaphoreObject, SemaphoreHandle);if (!EOS_SUCCESS(Status)) {ObDerefObject(SemaphoreObject);}return Status;}// semaphore 对象的signal 操作函数。