操作系统实验报告哈尔滨工程大学计算机科学与技术学院第四讲进程的同步一、实验概述1. 实验名称进程的同步2. 实验目的使用EOS的信号量,编程解决生产者—消费者问题,理解进程同步的意义。
调试跟踪EOS信号量的工作过程,理解进程同步的原理。
修改EOS的信号量算法,使之支持等待超时唤醒功能(有限等待),加深理解进程同步的原理。
3. 实验类型验证+设计4. 实验内容(1)准备实验(2)使用EOS的信号量解决生产者-消费者问题(3)调试EOS信号量的工作过程(4)修改EOS的信号量算法二、实验环境EOS操作系统和OS Lab集成实验环境,主要运用了C语言。
三、实验过程3. 需要解决的问题及解答(1)P143,生产者在生产了13号产品后本来要继续生产14号产品,可此时生产者为什么必须等待消费者消费了4号产品后,才能生产14号产品呢?生产者和消费者是怎样使用同步对象来实现该同步过程的呢?这是因为临界资源的限制。
临界资源就像产品仓库,只有“产品仓库”空闲生产者才能生产东西,有权向里面放东西。
因此它必须要等到消费者,取走产品,临界资源空闲时,才能继续生产14号产品。
(2)P147-四思考与练习-2. 绘制ps/semaphore.c文件内PsWaitForSemaphore和PsReleaseSemaphore函数的流程图。
5. 源程序并附上注释#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 INT Milliseconds,IN STATUS i )/*++功能描述:信号量的Wait 操作(P 操作)。
参数:Semaphore -- Wait 操作的信号量对象。
Milliseconds -- 等待超时上限,单位毫秒。
返回值:STATUS_SUCCESS。
--*/{BOOL IntState;ASSERT(KeGetIntNesting() == 0); // 中断环境下不能调用此函数。
IntState = KeEnableInterrupts(FALSE); // 开始原子操作,禁止中断。
// 目前仅实现了标准记录型信号量,不支持超时唤醒功能,所以PspWait 函数的第二个参数的值只能是INFINITE。
if(Semaphore->Count > 0){ Semaphore->Count--;i=STATUS_SUCCESS;}else {i=PspWait(&Semaphore->WaitListHead,Milliseconds );}KeEnableInterrupts(IntState); // 原子操作完成,恢复中断。
return i;}STATUSPsReleaseSemaphore(IN PSEMAPHORE Semaphore,IN LONG ReleaseCount,OUT PLONG PreviousCount)/*++功能描述:信号量的Signal 操作(V 操作)。
参数:Semaphore -- Wait 操作的信号量对象。
-- 信号量计数增加的数量。
当前只能为1。
当你修改信号量使之支持超时唤醒功能后,此参数的值能够大于等于1。
PreviousCount -- 返回信号量计数在增加之前的值。
返回值:如果成功释放信号量,返回STATUS_SUCCESS。
--*/{STATUS Status;BOOL 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))&&(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 struct _SEM_CREATE_PARAM{LONG InitialCount;LONG MaximumCount;}SEM_CREATE_PARAM, *PSEM_CREATE_PARAM;// semaphore 对象的构造函数,在创建新semaphore 对象时被调用。
VOIDPspOnCreateSemaphoreObject(IN PVOID SemaphoreObject,IN ULONG_PTR CreateParam){PsInitializeSemaphore( (PSEMAPHORE)SemaphoreObject,((PSEM_CREATE_PARAM)CreateParam)->InitialCount,((PSEM_CREATE_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_CREATE_PARAM CreateParam;if(InitialCount < 0 || MaximumCount <= 0 || InitialCount > MaximumCount){return STATUS_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 操作函数。
//STATUSPsReleaseSemaphoreObject(IN HANDLE Handle,IN LONG ReleaseCount,IN PLONG PreviousCount){STATUS Status;PSEMAPHORE Semaphore;if (ReleaseCount < 1) {return STATUS_INV ALID_PARAMETER;}// 由semaphore 句柄得到semaphore 对象的指针。
Status = ObRefObjectByHandle(Handle, PspSemaphoreType, (PVOID*)&Semaphore);if (EOS_SUCCESS(Status)) {Status = PsReleaseSemaphore(Semaphore, ReleaseCount, PreviousCount);ObDerefObject(Semaphore);}return Status;}#include "EOSApp.h"// 缓冲池。