实验三生产者与消费者.docx

上传人:b****6 文档编号:6332160 上传时间:2023-01-05 格式:DOCX 页数:21 大小:157.49KB
下载 相关 举报
实验三生产者与消费者.docx_第1页
第1页 / 共21页
实验三生产者与消费者.docx_第2页
第2页 / 共21页
实验三生产者与消费者.docx_第3页
第3页 / 共21页
实验三生产者与消费者.docx_第4页
第4页 / 共21页
实验三生产者与消费者.docx_第5页
第5页 / 共21页
点击查看更多>>
下载资源
资源描述

实验三生产者与消费者.docx

《实验三生产者与消费者.docx》由会员分享,可在线阅读,更多相关《实验三生产者与消费者.docx(21页珍藏版)》请在冰豆网上搜索。

实验三生产者与消费者.docx

实验三生产者与消费者

实验三:

生产者与消费者

一、实验目的

1.学习和掌握操作系统中进程之间的通信;

2.理解和掌握使用信号量机制来是想进程之间的同步和互斥;

3.学习使用创建文件对象,并利用文件映射对象来实现数据通信。

二、实验内容

•一个大小为6的缓冲区,初始为空,每个缓冲区能存放一个长度若为10个字符的字符串。

•2个生产者

–随机等待一段时间,往缓冲区添加数据,

–若缓冲区已满,等待消费者取走数据后再添加

–重复12次

•3个消费者

–随机等待一段时间,从缓冲区读取数据

–若缓冲区为空,等待生产者添加数据后再读取

–重复8次

说明:

•显示每次添加和读取数据的时间及缓冲区的状态

•生产者和消费者用进程模拟,缓冲区用共享内存来实现

三、实验环境

1.Windows下:

Windows8,Visualstudio2013

2.Linux下:

LinuxUbuntu4,gcc

四、程序设计与实现

1.Windows下:

A.主要函数说明:

(1)PROCESS_INFORMATIONStartClone(intnCloneID)

功能:

用来创建5个相同的进程,前两个为生产者,后三两个为消费者,赋予其不同的ID值,返回进程的信息。

(2)CreateSemaphore();

功能:

创建3个信号量:

full,empty,mutex。

来互斥的访问缓冲区,实现通信。

(3)CreateFileMapping()

功能:

在当前运行的进程中创建文件映射对象,来模拟共享缓冲区

MapViewOfFile()

功能:

在此文件映射上创建视图映射到当前应用程序的地址空间

B.程序流程图

 

 

创建3个信号量:

full,empty,mutex

创建共享内存

nClone=?

申请缓冲区

P(empty)

P(mutex)

把产品放入缓冲区:

将0置为1

释放缓冲区:

V(mutex)

V(full)

随机等待

12次放完了?

申请缓冲区

P(full)

P(mutex)

从缓冲区取产品:

将1置为0

释放缓冲区:

V(mutex)

V(empty)

随机等待

12次取完了?

等待子进程执行完毕

0

2

0

N

Y

Y

N

 

实验代码如下:

Windows:

//实验三.cpp:

定义控制台应用程序的入口点。

//

#include"stdafx.h"

#include

#include

#include

staticHANDLEhMutexMapping=INVALID_HANDLE_VALUE;

intnum=0;

HANDLElpHandle[10];

structbuf

{

intnum;

intread;

intwrite;

intbuffer[5];

};

BOOLStartClone()

{

inti;

BOOLbCreateOK;

PROCESS_INFORMATIONpi;

TCHARszFilename[MAX_PATH];

GetModuleFileName(NULL,szFilename,MAX_PATH);

TCHARszCmdLine[MAX_PATH];

for(i=0;i<3;i++)

{

sprintf(szCmdLine,"\"%s\"consumer%d",szFilename,i);

STARTUPINFOsi;

ZeroMemory(reinterpret_cast(&si),sizeof(si));

si.cb=sizeof(si);

bCreateOK=CreateProcess(

szFilename,

szCmdLine,

NULL,

NULL,

FALSE,

CREATE_DEFAULT_ERROR_MODE,

NULL,

NULL,

&si,

&pi);

if(!

bCreateOK)

{

returnfalse;

}

lpHandle[num]=pi.hProcess;

num++;

}

for(i=0;i<2;i++)

{

sprintf(szCmdLine,"\"%s\"productor%d",szFilename,i);

STARTUPINFOsi;

ZeroMemory(reinterpret_cast(&si),sizeof(si));

si.cb=sizeof(si);

bCreateOK=CreateProcess(

szFilename,

szCmdLine,

NULL,

NULL,

FALSE,

CREATE_DEFAULT_ERROR_MODE,

NULL,

NULL,

&si,

&pi);

if(!

bCreateOK)

{

returnfalse;

}

lpHandle[num]=pi.hProcess;

num++;

}

returntrue;

}

voidParent()

{

printf("Creatingthechildprocessandwaitedchildprocesstoquit.\n");

hMutexMapping=CreateMutex(NULL,true,"mutex");

HANDLEhMapping=CreateFileMapping(

NULL,

NULL,

PAGE_READWRITE,

0,

sizeof(LONG),

"map");

if(hMapping!

=INVALID_HANDLE_VALUE)

{

LPVOIDpData=MapViewOfFile(

hMapping,

FILE_MAP_ALL_ACCESS,

0,

0,

0);

if(pData!

=NULL)

{

ZeroMemory(pData,sizeof(LONG));

}

structbuf*pnData=reinterpret_cast(pData);

pnData->read=0;

pnData->write=0;

pnData->num=0;

memset(pnData->buffer,0,sizeof(pnData->buffer));

UnmapViewOfFile(pData);

}

CreateSemaphore(NULL,3,3,"EMPTY");

CreateSemaphore(NULL,0,3,"FULL");

BOOLbCreateOK=StartClone();

if(!

bCreateOK)

{

//printf("Createchildprocessfailed.\n");

}

else

{

//printf("Createchildprocesssuccess.\n");

}

ReleaseMutex(hMutexMapping);

}

voidProductor(intn)

{

intj;

printf("Productorisrunning.\n");

hMutexMapping=OpenMutex(MUTEX_ALL_ACCESS,true,"mutex");

HANDLEhMapping=OpenFileMapping(

FILE_MAP_ALL_ACCESS,

NULL,

"map");

if(hMapping==INVALID_HANDLE_VALUE)

{

printf("error\n");

}

HANDLEsemEmpty=OpenSemaphore(SEMAPHORE_ALL_ACCESS,FALSE,"EMPTY");

HANDLEsemFull=OpenSemaphore(SEMAPHORE_ALL_ACCESS,FALSE,"FULL");

for(inti=0;i<6;i++)

{

WaitForSingleObject(semEmpty,INFINITE);

SYSTEMTIMEst;

GetSystemTime(&st);

srand((unsigned)time(0));

Sleep(rand()/6);

WaitForSingleObject(hMutexMapping,INFINITE);

LPVOIDpFile=MapViewOfFile(

hMapping,

FILE_MAP_ALL_ACCESS,

0,

0,

0);

if(pFile!

=NULL)

{

structbuf*pnData=reinterpret_cast(pFile);

pnData->buffer[pnData->write]=1;

pnData->write=(pnData->write+1)%3;

pnData->num++;

printf("%02d:

%02d:

%02d生产者[%d]生产成功缓冲区中剩余%d个",st.wHour,st.wMinute,st.wSecond,n,pnData->num);

for(j=0;j<3;j++)

{

printf("%d",pnData->buffer[j]);

}

printf("\n");

}

UnmapViewOfFile(pFile);

pFile=NULL;

ReleaseSemaphore(semFull,1,NULL);

ReleaseMutex(hMutexMapping);

}

printf("生产者[%d]生产完毕\n",n);

}

voidConsumer(intn)

{

intj;

printf("Consumerisrunning.\n");

hMutexMapping=OpenMutex(MUTEX_ALL_ACCESS,true,"mutex");

HANDLEhMapping=OpenFileMapping(

FILE_MAP_ALL_ACCESS,

NULL,

"map");

if(hMapping==INVALID_HANDLE_VALUE)

{

printf("error\n");

}

HANDLEsemEmpty=OpenSemaphore(SEMAPHORE_ALL_ACCESS,FALSE,"EMPTY");

HANDLEsemFull=OpenSemaphore(SEMAPHORE_ALL_ACCESS,FALSE,"FULL");

for(inti=0;i<4;i++)

{

WaitForSingleObject(semFull,INFINITE);

SYSTEMTIMEst;

GetSystemTime(&st);

srand((unsigned)time(0));

Sleep(rand()/6);

WaitForSingleObject(hMutexMapping,INFINITE);

LPVOIDpFile=MapViewOfFile(

hMapping,

FILE_MAP_ALL_ACCESS,

0,

0,

0);

if(pFile!

=NULL)

{

structbuf*pnData=reinterpret_cast(pFile);

pnData->buffer[pnData->read]=0;

pnData->read=(pnData->read+1)%3;

pnData->num--;

printf("%02d:

%02d:

%02d消费者[%d]消费成功缓冲区中剩余%d个",st.wHour,st.wMinute,st.wSecond,n,pnData->num);

for(j=0;j<3;j++)

{

printf("%d",pnData->buffer[j]);

}

printf("\n");

}

UnmapViewOfFile(pFile);

pFile=NULL;

ReleaseSemaphore(semEmpty,1,NULL);

ReleaseMutex(hMutexMapping);

}

printf("消费者[%d]消费完毕\n",n);

}

intmain(intargc,char**argv)

{

if(argc>1&&strcmp(argv[1],"productor")==0)

{

Productor(atoi(argv[2]));

}

elseif(argc>1&&strcmp(argv[1],"consumer")==0)

{

Consumer(atoi(argv[2]));

}

else

{

Parent();

WaitForMultipleObjects(num,lpHandle,true,INFINITE);

}

return0;

}

Linux下代码:

//主进程

#include

#include

#include"head.h"

intmain()

{

intid=semget(SEM_ALL_KEY,3,IPC_CREAT|0660);//创建信号量集合

//初始化信号量集合

semctl(id,SEM_EMPTY,SETVAL,3);

semctl(id,SEM_FULL,SETVAL,0);

semctl(id,SEM_MUTEX,SETVAL,1);

intshmid=createQueue();//创建共享主存

if(shmid<0)

{

perror("createshmerror.");

exit

(1);

}

//生成生产者进程

if(fork()==0)

execl("producer","producer1",0);

if(fork()==0)

execl("producer","producer2",0);

//生成消费者进程

if(fork()==0)

execl("consumer","consumer1",0);

if(fork()==0)

execl("consumer","consumer2",0);

if(fork()==0)

execl("consumer","consumer3",0);

//等待子进程

intstat,i;

for(i=0;i<5;i++)

wait(&stat);

removeQueue(shmid);//释放共享主存return0;

}

/*生产者*/

#include"head.h"

main(intargc,char*argv[])

{

structqueue*buf,*out;

intsem_id=semget(SEM_ALL_KEY,3,IPC_CREAT|0660);

inti,j;

buf=getQueue();//打开共享主存

out=buf;

for(i=0;i<6;i++)

{

p(sem_id,SEM_EMPTY);//P(EMPTY),EMPTY开始值为3,表明有三个空余,申请一个之后,有两个空余,当为零时,不再往里面写数据

p(sem_id,SEM_MUTEX);//P(MUTEX),MUTEX开始值为1,表明一次只能运行一个进程

buf->buf++;//产品数+1

(buf+buf->buf)->buf=1;//放入产品后缓冲区置1

//获取当前时间

structtimevalcurtime;

gettimeofday(&curtime,NULL);

//输出信息

printf("No.%sputproduct%ld:

%ld"

argv[0],curtime.tv_sec,curtime.tv_usec);

printf("Nowthebufferis");

for(j=1;j<=3;j++)

printf("%4d",(out+j)->buf);

printf("\n");

v(sem_id,SEM_MUTEX);//V(MUTEX)

v(sem_id,SEM_FULL);//V(FULL),释放一个FULL,即往里面写了一个数据

//随机sleep一会

intran=random()%5;

sleep(ran);

}

}

/*消费者*/

#include"head.h"

main(intargc,char*argv[])

{

structqueue*buf,*out;

intsem_id=semget(SEM_ALL_KEY,3,IPC_CREAT|0660);

inti,j;

buf=getQueue();//打开共享主存

out=buf;

for(i=0;i<4;i++)

{

p(sem_id,SEM_FULL);//P(FULL)FULL开始值为0,表明开始的时候没有数据,无法取得,当producer释放一个数据时,这里开始有数据

p(sem_id,SEM_MUTEX);//P(MUTEX)

(buf+buf->buf)->buf=0;//取出产品后缓冲区置0

buf->buf--;//产品数-1

//获取当前时间

structtimevalcurtime;

gettimeofday(&curtime,NULL);

//输出信息

printf("No.%sgetproduct%ld:

%ld"

argv[0],curtime.tv_sec,curtime.tv_usec);

printf("Nowthebufferis");

for(j=1;j<=3;j++)

printf("%4d",(out+j)->buf);

printf("\n");

v(sem_id,SEM_MUTEX);//V(MUTEX)

v(sem_id,SEM_EMPTY);//V(EMPTY)

//随机等待一段时间

intran=random()%5;

sleep(ran);

}

}

Windows运行截图:

Linux下截图:

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

当前位置:首页 > 经管营销 > 生产经营管理

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

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