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下截图: