实例介绍
【实例截图】
【核心代码】
# 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; }
标签:
相关软件
小贴士
感谢您为本站写下的评论,您的评论对其它用户来说具有重要的参考价值,所以请认真填写。
- 类似“顶”、“沙发”之类没有营养的文字,对勤劳贡献的楼主来说是令人沮丧的反馈信息。
- 相信您也不想看到一排文字/表情墙,所以请不要反馈意义不大的重复字符,也请尽量不要纯表情的回复。
- 提问之前请再仔细看一遍楼主的说明,或许是您遗漏了。
- 请勿到处挖坑绊人、招贴广告。既占空间让人厌烦,又没人会搭理,于人于己都无利。
关于好例子网
本站旨在为广大IT学习爱好者提供一个非营利性互相学习交流分享平台。本站所有资源都可以被免费获取学习研究。本站资源来自网友分享,对搜索内容的合法性不具有预见性、识别性、控制性,仅供学习研究,请务必在下载后24小时内给予删除,不得用于其他任何用途,否则后果自负。基于互联网的特殊性,平台无法对用户传输的作品、信息、内容的权属或合法性、安全性、合规性、真实性、科学性、完整权、有效性等进行实质审查;无论平台是否已进行审查,用户均应自行承担因其传输的作品、信息、内容而可能或已经产生的侵权或权属纠纷等法律责任。本站所有资源不代表本站的观点或立场,基于网友分享,根据中国法律《信息网络传播权保护条例》第二十二与二十三条之规定,若资源存在侵权或相关问题请联系本站客服人员,点此联系我们。关于更多版权及免责申明参见 版权及免责申明
网友评论
我要评论