基本信息
源码名称:生产者消费者(WindowsPC.cpp)
源码大小:5.57KB
文件格式:.cpp
开发语言:C/C++
更新时间:2020-12-07
友情提示:(无需注册或充值,赞助后即可获取资源下载链接)
嘿,亲!知识可是无价之宝呢,但咱这精心整理的资料也耗费了不少心血呀。小小地破费一下,绝对物超所值哦!如有下载和支付问题,请联系我们QQ(微信同号):813200300
本次赞助数额为: 2 元×
微信扫码支付:2 元
×
请留下您的邮箱,我们将在2小时内将文件发到您的邮箱
源码介绍
# include <windows.h> # include <stdio.h> # include <stdlib.h> # include <time.h> PROCESS_INFORMATION StartClone(int nCloneID); int main(int argc, char* argv[] ) { int nClone=0 ; int i,time,j; HANDLE SEM_FULL; HANDLE SEM_EMPTY; HANDLE SEM_MUTEX; HANDLE hMap; PROCESS_INFORMATION nH[5]; int *pData,*out; if (argc > 1) { // 从第二个参数中提取克隆ID sscanf(argv[1] , "%d" , &nClone) ; } if(nClone==0) //主进程,创建5个子进程,前2个为生产者,后3个为消费者 { //建立信号量 SEM_FULL=CreateSemaphore(NULL,0,3,"FULL"); SEM_EMPTY=CreateSemaphore(NULL,3,3,"EMPTY"); SEM_MUTEX=CreateSemaphore(NULL,1,1,"MUTEX"); //建立共享内存 HANDLE CurrentProcess = GetCurrentProcess(); hMap = CreateFileMapping ( CurrentProcess, //在当前进程中创建文件映射 NULL, //默认的安全性 PAGE_READWRITE, //可读写权 0, //最大尺寸(高32位) sizeof(int)*4, //最小尺寸(低32位) "buffer"); //该文件映射的作为共享内存的缓冲区,取名为“buffer” //在文件映射上创建视图 pData = (int*)MapViewOfFile ( hMap, //保存文件的对象 FILE_MAP_WRITE, //映射可读可写 0, //在文件的开头处(高32位)开始 0, //在文件的开头处(低32位) sizeof(int)*4); //整个文件要映射4个字节 if(pData != NULL) { ZeroMemory(pData,sizeof(int)*4); //分配内存空间,并清零 } out=pData; //建立5个子进程 for (i=0;i<5;i ) { nH[i]=StartClone( nClone); } //等待子进程结束 for(i=0;i<5;i ) WaitForSingleObject(nH[i].hProcess,INFINITE); //关闭子进程句柄 for (i=0;i<5;i ) { CloseHandle(nH[i].hProcess); CloseHandle(nH[i].hThread); } //关闭句柄 CloseHandle(SEM_MUTEX); CloseHandle(hMap); CloseHandle(SEM_EMPTY); CloseHandle(SEM_FULL); } else if (nClone > 0 &&nClone < 3) //2个生产者 { for (i=0;i<6;i ) { //获得句柄 SEM_EMPTY=OpenSemaphore(SEMAPHORE_ALL_ACCESS,NULL,"EMPTY"); SEM_FULL=OpenSemaphore(SEMAPHORE_ALL_ACCESS,NULL,"FULL"); SEM_MUTEX=OpenSemaphore(SEMAPHORE_ALL_ACCESS,NULL,"MUTEX"); hMap = OpenFileMapping(FILE_MAP_WRITE,FALSE,"buffer"); pData = (int*)MapViewOfFile (hMap, FILE_MAP_WRITE, 0, 0, sizeof(int)*4); out=pData; //p 申请信号量 WaitForSingleObject(SEM_EMPTY, INFINITE); WaitForSingleObject(SEM_MUTEX, INFINITE); //向缓冲区添加产品,把0置为1 (*pData) ; *(pData (*pData))=1; //获得时间 SYSTEMTIME curtime; GetSystemTime(&curtime); //输出状态 printf("生产者%d 写入数据 时间:%02d:%02d:%02d:%03d.\n " ,nClone,curtime.wHour,curtime.wMinute,curtime.wSecond,curtime.wMilliseconds); printf(" 缓存区内容为: "); for (j=1;j<=3;j ) { printf("%4d",*(out j)); } printf("\n"); //释放信号量 ReleaseSemaphore(SEM_MUTEX,1,NULL); ReleaseSemaphore(SEM_FULL,1,NULL); //关闭句柄 CloseHandle(SEM_MUTEX); CloseHandle(SEM_EMPTY); CloseHandle(SEM_FULL); CloseHandle(hMap); //随机等待 time = rand()%450; Sleep(time); } } else if(nClone>2 && nClone< 6) //3个消费者 { //获得句柄 for (i=0;i<4;i ) { SEM_EMPTY=OpenSemaphore(SEMAPHORE_ALL_ACCESS,NULL,"EMPTY"); SEM_FULL=OpenSemaphore(SEMAPHORE_ALL_ACCESS,NULL,"FULL"); SEM_MUTEX=OpenSemaphore(SEMAPHORE_ALL_ACCESS,NULL,"MUTEX"); hMap = OpenFileMapping(FILE_MAP_WRITE,FALSE,"buffer"); pData = (int*)MapViewOfFile (hMap, FILE_MAP_WRITE, 0, 0, sizeof(int)*4); out=pData; WaitForSingleObject(SEM_FULL, INFINITE); WaitForSingleObject(SEM_MUTEX, INFINITE); SYSTEMTIME curtime; GetSystemTime(&curtime); //取产品,将1置为0 *(pData (*pData))=0; (*pData)--; //输出当前信息 printf("消费者%d 取出数据 时间:%02d:%02d:%02d:%03d.\n" ,nClone-2,curtime.wHour,curtime.wMinute,curtime.wSecond,curtime.wMilliseconds); printf(" 缓存区内容为: "); for (j=1;j<=3;j ) { printf("%4d",*(out j)); } printf("\n"); //释放信号量 ReleaseSemaphore(SEM_MUTEX,1,NULL); ReleaseSemaphore(SEM_EMPTY,1,NULL); //关闭句柄 CloseHandle(SEM_MUTEX); CloseHandle(SEM_EMPTY); CloseHandle(SEM_FULL); CloseHandle(hMap); //随机等待 time = rand()%1000; Sleep(time); } } return 0; } // 创建一个克隆的进程并赋于其ID值,并返回进程和线程信息 PROCESS_INFORMATION StartClone(int nCloneID) { // 获得用于当前可执行文件的文件名 TCHAR szFilename[MAX_PATH] ; GetModuleFileName(NULL, szFilename, MAX_PATH) ; //创建子进程命令行的格式化,获得应用程序的EXE文件名并克隆进程的ID值 TCHAR szCmdLine[MAX_PATH] ; sprintf(szCmdLine, "\"%s\" %d", szFilename, nCloneID) ; STARTUPINFO si; // 用于子进程的STARTUPINFO结构 ZeroMemory(reinterpret_cast <void*> (&si) , sizeof(si) ) ; // reinterpret_cast为数据类型转换操作 si.cb = sizeof(si) ; PROCESS_INFORMATION pi; // 说明一个用于记录子进程的相关信息的结构变量 // 利用同样的可执行文件和命令行创建进程 BOOL bCreateOK = CreateProcess( szFilename, // 可执行的应用程序的名称 szCmdLine, // 指定创建一个子进程的符号标识 NULL, // 缺省的进程安全性 NULL, // 缺省的线程安全性 FALSE, // 不继承打开文件的句柄 NULL, // 不使用新的控制台 NULL, // 新的环境 NULL, // 当前目录 &si, // 启动信息 &pi) ; // 返回进程和线程信息 // 运行结束,关闭进程和其线程的句柄 return pi; }