实验五.docx

上传人:b****6 文档编号:7917894 上传时间:2023-01-27 格式:DOCX 页数:16 大小:428.44KB
下载 相关 举报
实验五.docx_第1页
第1页 / 共16页
实验五.docx_第2页
第2页 / 共16页
实验五.docx_第3页
第3页 / 共16页
实验五.docx_第4页
第4页 / 共16页
实验五.docx_第5页
第5页 / 共16页
点击查看更多>>
下载资源
资源描述

实验五.docx

《实验五.docx》由会员分享,可在线阅读,更多相关《实验五.docx(16页珍藏版)》请在冰豆网上搜索。

实验五.docx

实验五

操作系统

实验报告

课程名称

操作系统实验

课程编号

0920311

实验项目名称

进程的同步

学号

年级

姓名

专业

软件工程

学生所在学院

软件学院

指导教师

实验室名称地点

计算机软件第二实验室21#427

哈尔滨工程大学

软件学院

第四讲进程的同步

一、实验概述

1.实验名称

进程的同步

2.实验目的

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

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

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

3.实验类型(验证、设计)

验证+设计

4.实验内容

1准备实验

2使用EOS的信号量解决生产者-消费者问题

3调试EOS信号量的工作过程

3.1创建信号量

3.2等待、释放信号量

3.2.1等待信号量(不阻塞)

3.2.2释放信号量(不唤醒)

3.2.3等待信号量(阻塞)

3.2.4释放信号量(唤醒)

4修改EOS的信号量算法

4.1要求

4.2提示

4.3测试方法

二、实验环境

环境:

WindowsXP + EOS集成实验环境

语言:

c语言

三、实验过程

1.设计思路和流程图

图1.1Main函数流程图

图1.2Producer函数流程图

图1.3Consumer函数流程图

2.算法实现

3.需要解决的问题及解答

(1)P143,生产者在生产了13号产品后本来要继续生产14号产品,可此时生产者为什么必须等待消费者消费了4号产品后,才能生产14号产品呢?

生产者和消费者是怎样使用同步对象来实现该同步过程的呢?

答:

这是因为临界资源的限制。

临界资源就像产品仓库,只有仓库空闲,生产者才能生产,有权向里面放东西。

所以必须等到消费者取走产品后,临界资源空闲时才能继续生产14号产品。

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

PsWaitForSemaphore函数的流程图

PsReleaseSemaphore函数的流程图

4.主要数据结构、实现代码及其说明

修改PsWaitForSemaphore

if(Semaphore->Count>0){

Semaphore->Count--;

ans=STATUS_SUCCESS;}

elseif(Semaphore->Count==0)

ans=PspWait(&Semaphore->WaitListHead,Milliseconds);

else{

PspWait(&Semaphore->WaitListHead,INFINITE);

}

KeEnableInterrupts(IntState);//原子操作完成,恢复中断。

returnans;

修改PsReleaseSemaphore

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

if(Semaphore->Count+ReleaseCount>Semaphore->MaximumCount){

Status=STATUS_SEMAPHORE_LIMIT_EXCEEDED;

}else{

//记录当前的信号量的值。

if(NULL!

=PreviousCount){

*PreviousCount=Semaphore->Count;

}

//目前仅实现了标准记录型信号量,每执行一次信号量的释放操作

//只能使信号量的值增加1。

intk=Semaphore->Count+ReleaseCount;

while((!

ListIsEmpty(&Semaphore->WaitListHead))&&(k))

{

PspWakeThread(&Semaphore->WaitListHead,STATUS_SUCCESS);

k--;

}

Semaphore->Count=k;

//可能有线程被唤醒,执行线程调度。

PspThreadSchedule();

Status=STATUS_SUCCESS;

}

KeEnableInterrupts(IntState);//原子操作完成,恢复中断。

returnStatus;

5.源程序并附上注释

#include"psp.h"

VOID

PsInitializeSemaphore(

INPSEMAPHORESemaphore,

INLONGInitialCount,

INLONGMaximumCount

/*++功能描述:

初始化信号量结构体。

参数:

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

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

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

返回值:

无。

--*/

{

ASSERT(InitialCount>=0&&InitialCount<=MaximumCount&&MaximumCount>0);

Semaphore->Count=InitialCount;

Semaphore->MaximumCount=MaximumCount;

ListInitializeHead(&Semaphore->WaitListHead);

}

STATUS

PsWaitForSemaphore(

INPSEMAPHORESemaphore,

INULONGMilliseconds

/*++

功能描述:

信号量的Wait操作(P操作)。

参数:

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

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

返回值:

STATUS_SUCCESS。

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

--*/

{

STATUSans=STATUS_SUCCESS;

BOOLIntState;

ASSERT(KeGetIntNesting()==0);//中断环境下不能调用此函数。

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

//目前仅实现了标准记录型信号量,不支持超时唤醒功能,所以PspWait函数

//的第二个参数的值只能是INFINITE。

if(Semaphore->Count>0){

Semaphore->Count--;

ans=STATUS_SUCCESS;}

elseif(Semaphore->Count==0)

ans=PspWait(&Semaphore->WaitListHead,Milliseconds);

else{

PspWait(&Semaphore->WaitListHead,INFINITE);

}

KeEnableInterrupts(IntState);//原子操作完成,恢复中断。

returnans;

}

STATUS

PsReleaseSemaphore(

INPSEMAPHORESemaphore,

INLONGReleaseCount,

OUTPLONGPreviousCount

/*++功能描述:

信号量的Signal操作(V操作)。

参数:

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

ReleaseCount--信号量计数增加的数量。

当前只能为1。

当你修改信号量使之支持

超时唤醒功能后,此参数的值能够大于等于1。

PreviousCount--返回信号量计数在增加之前的值。

返回值:

如果成功释放信号量,返回STATUS_SUCCESS。

--*/

{

STATUSStatus;

BOOLIntState;

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

if(Semaphore->Count+ReleaseCount>Semaphore->MaximumCount){

Status=STATUS_SEMAPHORE_LIMIT_EXCEEDED;

}else{

//记录当前的信号量的值。

if(NULL!

=PreviousCount){

*PreviousCount=Semaphore->Count;

}

//目前仅实现了标准记录型信号量,每执行一次信号量的释放操作

//只能使信号量的值增加1。

intk=Semaphore->Count+ReleaseCount;

while((!

ListIsEmpty(&Semaphore->WaitListHead))&&(k))

{

PspWakeThread(&Semaphore->WaitListHead,STATUS_SUCCESS);

k--;

}

Semaphore->Count=k;

//可能有线程被唤醒,执行线程调度。

PspThreadSchedule();

Status=STATUS_SUCCESS;

}

KeEnableInterrupts(IntState);//原子操作完成,恢复中断。

returnStatus;

}

//下面是和信号量对象类型相关的代码。

//信号量对象类型指针。

POBJECT_TYPEPspSemaphoreType=NULL;

//用于初始化semaphore结构体的参数结构体。

typedefstruct_SEM_CREATE_PARAM{

LONGInitialCount;

LONGMaximumCount;

}SEM_CREATE_PARAM,*PSEM_CREATE_PARAM;

//semaphore对象的构造函数,在创建新semaphore对象时被调用。

VOID

PspOnCreateSemaphoreObject(

INPVOIDSemaphoreObject,

INULONG_PTRCreateParam)

{

PsInitializeSemaphore((PSEMAPHORE)SemaphoreObject,

((PSEM_CREATE_PARAM)CreateParam)->InitialCount,

((PSEM_CREATE_PARAM)CreateParam)->MaximumCount);

}

//semaphore对象类型的初始化函数。

VOID

PspCreateSemaphoreObjectType(VOID)

{

STATUSStatus;

OBJECT_TYPE_INITIALIZERInitializer;

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("Failedtocreatesemaphoreobjecttype!

");

}

}

//semaphore对象的构造函数。

STATUS

PsCreateSemaphoreObject(

INLONGInitialCount,

INLONGMaximumCount,

INPSTRName,

OUTPHANDLESemaphoreHandle

{

STATUSStatus;

PVOIDSemaphoreObject;

SEM_CREATE_PARAMCreateParam;

if(InitialCount<0||MaximumCount<=0||InitialCount>MaximumCount){

returnSTATUS_INVALID_PARAMETER;

}

//创建信号量对象。

CreateParam.InitialCount=InitialCount;

CreateParam.MaximumCount=MaximumCount;

Status=ObCreateObject(PspSemaphoreType,

Name,

sizeof(SEMAPHORE),

(ULONG_PTR)&CreateParam,

&SemaphoreObject);

if(!

EOS_SUCCESS(Status)){

returnStatus;

}

Status=ObCreateHandle(SemaphoreObject,SemaphoreHandle);

if(!

EOS_SUCCESS(Status)){

ObDerefObject(SemaphoreObject);

}

returnStatus;

}

//semaphore对象的signal操作函数。

STATUS

PsReleaseSemaphoreObject(

INHANDLEHandle,

INLONGReleaseCount,

INPLONGPreviousCount

{

STATUSStatus;

PSEMAPHORESemaphore;

if(ReleaseCount<1){

returnSTATUS_INVALID_PARAMETER;

}

//由semaphore句柄得到semaphore对象的指针。

Status=ObRefObjectByHandle(Handle,PspSemaphoreType,(PVOID*)&Semaphore);

if(EOS_SUCCESS(Status)){

Status=PsReleaseSemaphore(Semaphore,ReleaseCount,PreviousCount);

ObDerefObject(Semaphore);

}

returnStatus;

}

6.程序运行时的初值和运行结果

四、实验体会

过本次实验,初步了解操作系统的进程同步的过程。

我对生产者-消费者问题的解决办法有了更全面的认识,同时对调试代码更加熟练。

这次上机练习一步一步按照试验知道上的内容操作,最后也得到了想要的结果。

虽然这个实验的时间较长,但感觉很充实。

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

当前位置:首页 > 高等教育 > 工学

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

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