《实验三:生产者与消费者(共20页).docx》由会员分享,可在线阅读,更多相关《实验三:生产者与消费者(共20页).docx(20页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。
1、精选优质文档-倾情为你奉上实验三:生产者与消费者一、 实验目的1.学习和掌握操作系统中进程之间的通信;2.理解和掌握使用信号量机制来是想进程之间的同步和互斥;3.学习使用创建文件对象,并利用文件映射对象来实现数据通信。二、实验内容 一个大小为6的缓冲区,初始为空,每个缓冲区能存放一个长度若为10个字符的字符串。 2个生产者 随机等待一段时间,往缓冲区添加数据, 若缓冲区已满,等待消费者取走数据后再添加 重复12次 3个消费者 随机等待一段时间,从缓冲区读取数据 若缓冲区为空,等待生产者添加数据后再读取 重复8次说明: 显示每次添加和读取数据的时间及缓冲区的状态 生产者和消费者用进程模拟,缓冲区
2、用共享内存来实现三、 实验环境1. Windows下:Windows8 ,Visual studio 20132. Linux下:Linux Ubuntu 4,gcc四、 程序设计与实现1. Windows下:A 主要函数说明:(1) PROCESS_INFORMATIONStartClone(intnCloneID)功能:用来创建5个相同的进程,前两个为生产者,后三两个为消费者,赋予其不同的ID值,返回进程的信息。(2) CreateSemaphore();功能:创建3个信号量:full,empty,mutex。来互斥的访问缓冲区,实现通信。(3) CreateFileMapping()功能
3、:在当前运行的进程中创建文件映射对象,来模拟共享缓冲区MapViewOfFile()功能:在此文件映射上创建视图映射到当前应用程序的地址空间B 程序流程图开始初始化:创建的子进程个数为0nClone=0;创建5个相同的子进程nClone+2nClone60nClone3申请缓冲区P(full)P(mutex)申请缓冲区P(empty)P(mutex)nClone=?0从缓冲区取产品:将1置为0创建3个信号量:full ,empty,mutex把产品放入缓冲区:将0置为1释放缓冲区:V(mutex)V(empty)释放缓冲区:V(mutex)V(full)创建共享内存NN随机等待随机等待等待子进
4、程执行完毕12次取完了?12次放完了?YY结束每个子进程结束实验代码如下:Windows:/ 实验三.cpp : 定义控制台应用程序的入口点。/#include stdafx.h#include #include #include static HANDLE hMutexMapping=INVALID_HANDLE_VALUE; int num=0; HANDLE lpHandle10; struct buf int num; int read; int write; int buffer5; ; BOOL StartClone() int i; BOOL bCreateOK; PROCESS
5、_INFORMATION pi; TCHAR szFilenameMAX_PATH; GetModuleFileName(NULL,szFilename,MAX_PATH); TCHAR szCmdLineMAX_PATH; for ( i = 0; i 3; i+) sprintf(szCmdLine,%s consumer %d,szFilename,i); STARTUPINFO si; ZeroMemory(reinterpret_cast(&si),sizeof(si); si.cb=sizeof(si); bCreateOK=CreateProcess( szFilename, s
6、zCmdLine, NULL, NULL, FALSE, CREATE_DEFAULT_ERROR_MODE, NULL, NULL, &si, &pi); if (!bCreateOK) return false; lpHandlenum=pi.hProcess; num+; for ( i = 0; i 2; i+) sprintf(szCmdLine,%s productor %d,szFilename,i); STARTUPINFO si; ZeroMemory(reinterpret_cast(&si),sizeof(si); si.cb=sizeof(si); bCreateOK=
7、CreateProcess( szFilename, szCmdLine, NULL, NULL, FALSE, CREATE_DEFAULT_ERROR_MODE, NULL, NULL, &si, &pi); if (!bCreateOK) return false; lpHandlenum=pi.hProcess; num+; return true; void Parent() printf(Creating the child process and waited child process to quit.n); hMutexMapping=CreateMutex(NULL,tru
8、e,mutex); HANDLE hMapping=CreateFileMapping( NULL, NULL, PAGE_READWRITE, 0, sizeof(LONG), map); if (hMapping!=INVALID_HANDLE_VALUE) LPVOID pData=MapViewOfFile( hMapping, FILE_MAP_ALL_ACCESS, 0, 0, 0); if (pData!=NULL) ZeroMemory(pData,sizeof(LONG); struct buf *pnData=reinterpret_cast(pData); pnData-
9、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); BOOL bCreateOK=StartClone(); if (!bCreateOK) /printf(Create child process failed.n); else /printf(Create child process success.
10、n); ReleaseMutex(hMutexMapping); void Productor(int n) int j; printf(Productor is running.n); hMutexMapping=OpenMutex(MUTEX_ALL_ACCESS,true,mutex); HANDLE hMapping=OpenFileMapping( FILE_MAP_ALL_ACCESS, NULL, map); if (hMapping=INVALID_HANDLE_VALUE) printf(errorn); HANDLE semEmpty = OpenSemaphore(SEM
11、APHORE_ALL_ACCESS,FALSE,EMPTY); HANDLE semFull = OpenSemaphore(SEMAPHORE_ALL_ACCESS,FALSE,FULL); for (int i = 0; i 6; i+) WaitForSingleObject(semEmpty, INFINITE); SYSTEMTIME st; GetSystemTime(&st); srand(unsigned)time(0); Sleep(rand()/6); WaitForSingleObject(hMutexMapping,INFINITE); LPVOID pFile=Map
12、ViewOfFile( hMapping, FILE_MAP_ALL_ACCESS, 0, 0, 0); if (pFile!=NULL) struct buf *pnData=reinterpret_cast(pFile); pnData-bufferpnData-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 bufferj)
13、; printf(n); UnmapViewOfFile(pFile); pFile=NULL; ReleaseSemaphore(semFull, 1, NULL); ReleaseMutex(hMutexMapping); printf(生产者%d生产完毕n,n); void Consumer(int n) int j; printf(Consumer is running.n); hMutexMapping=OpenMutex(MUTEX_ALL_ACCESS,true,mutex); HANDLE hMapping=OpenFileMapping( FILE_MAP_ALL_ACCES
14、S, NULL, map); if (hMapping=INVALID_HANDLE_VALUE) printf(errorn); HANDLE semEmpty = OpenSemaphore(SEMAPHORE_ALL_ACCESS,FALSE,EMPTY); HANDLE semFull = OpenSemaphore(SEMAPHORE_ALL_ACCESS,FALSE,FULL); for (int i = 0; i 4; i+) WaitForSingleObject(semFull, INFINITE); SYSTEMTIME st; GetSystemTime(&st); sr
15、and(unsigned)time(0); Sleep(rand()/6); WaitForSingleObject(hMutexMapping,INFINITE); LPVOID pFile=MapViewOfFile( hMapping, FILE_MAP_ALL_ACCESS, 0, 0, 0); if (pFile!=NULL) struct buf *pnData=reinterpret_cast(pFile); pnData-bufferpnData-read=0; pnData-read=(pnData-read+1)%3; pnData-num-; printf(%02d:%0
16、2d:%02d 消费者%d消费成功 缓冲区中剩余%d个 ,st.wHour,st.wMinute,st.wSecond,n,pnData-num); for (j = 0; j bufferj); printf(n); UnmapViewOfFile(pFile); pFile=NULL; ReleaseSemaphore(semEmpty,1,NULL); ReleaseMutex(hMutexMapping); printf(消费者%d消费完毕n,n); int main(int argc,char *argv) if (argc1&strcmp(argv1,productor)=0) P
17、roductor(atoi(argv2); else if (argc1&strcmp(argv1,consumer)=0) Consumer(atoi(argv2); else Parent(); WaitForMultipleObjects(num,lpHandle,true,INFINITE); return 0; Linux下代码:/主进程#include #include #include head.hint main()int id = semget(SEM_ALL_KEY, 3, IPC_CREAT|0660);/创建信号量集合/初始化信号量集合semctl(id, SEM_EM
18、PTY, SETVAL, 3);semctl(id, SEM_FULL, SETVAL, 0);semctl(id, SEM_MUTEX, SETVAL, 1);int shmid = createQueue();/创建共享主存if(shmid0)perror(create shm error.);exit(1);/生成生产者进程if(fork()=0)execl(producer, producer1, 0);if(fork()=0)execl(producer, producer2, 0);/生成消费者进程if(fork()=0)execl(consumer, consumer1, 0);
19、if(fork()=0)execl(consumer, consumer2, 0);if(fork()=0)execl(consumer, consumer3, 0);/等待子进程int stat,i;for(i=0;i5;i+)wait(&stat);removeQueue(shmid);/释放共享主存return 0;/*生产者*/#include head.hmain(int argc,char * argv)struct queue *buf,*out;int sem_id = semget(SEM_ALL_KEY,3, IPC_CREAT|0660);int i,j;buf = ge
20、tQueue();/打开共享主存out = buf;for(i=0;ibuf+;/产品数+1(buf + buf-buf) -buf = 1;/放入产品后缓冲区置1/获取当前时间struct timeval curtime;gettimeofday(&curtime,NULL);/输出信息printf(No.%s put product %ld:%ld ,argv0,curtime.tv_sec,curtime.tv_usec);printf(Now the buffer is );for(j=1;jbuf);printf(n);v(sem_id, SEM_MUTEX);/V(MUTEX)v(
21、sem_id, SEM_FULL);/V(FULL),释放一个FULL,即往里面写了一个数据/随机 sleep 一会int ran=random()%5;sleep(ran);/*消费者*/#include head.hmain(int argc,char * argv)struct queue *buf,*out;int sem_id = semget(SEM_ALL_KEY, 3, IPC_CREAT|0660);int i,j;buf = getQueue();/打开共享主存out = buf;for(i=0;ibuf) -buf = 0;/取出产品后缓冲区置0buf-buf-; /产品
22、数-1/获取当前时间struct timeval curtime;gettimeofday(&curtime,NULL);/输出信息printf(No.%s get product %ld:%ld ,argv0,curtime.tv_sec,curtime.tv_usec);printf(Now the buffer is );for(j=1;jbuf);printf(n);v(sem_id, SEM_MUTEX);/V(MUTEX)v(sem_id, SEM_EMPTY);/V(EMPTY)/随机等待一段时间int ran=random()%5;sleep(ran);Windows运行截图:Linux下截图:专心-专注-专业