Windows进程控制实现生产者消费者问题

写得非常艰难的多进程代码,很多细节要注意,主要是自己的思路不够清晰。实现的比较丑陋,各位见笑了。


#include<windows.h>
#include<iostream>
#include <sys/time.h> 
static LPCTSTR mutex_read_name="read";//生产者互斥访问缓冲区
static LPCTSTR mutex_write_name="write";//消费者互斥访问缓冲区
static LPCTSTR mutex_print_name="print";//生产者消费者互斥打印避免混合输出 如果缓冲区只有一个mutex则可以不用此变量
static LPCTSTR event_continue_name="continue";//为了避免创建子进程顺序造成的影响 子进程等待同一信号一起开始
static LPCTSTR sem_full="full";
static LPCTSTR sem_empty="empty";
static LPCTSTR filemapping_name="filemapping";
char a[3]={'L','S','W'};
void SignalStart()
{
	HANDLE hEventContinue=OpenEvent(
		EVENT_MODIFY_STATE,
		FALSE,
		event_continue_name);
	if(hEventContinue!=NULL)
	{
		SetEvent(hEventContinue);
	}
	CloseHandle(hEventContinue);
 } 
BOOL CreateChild(char* process)
{
	TCHAR szFilename[MAX_PATH];
	GetModuleFileName(NULL,szFilename,MAX_PATH);//第一个参数为NULL获取当前程序路径
	TCHAR szCmdLine[MAX_PATH];
	sprintf(szCmdLine,"\"%s\" %s",szFilename,process);
	printf("line:%s\n",szCmdLine);
	STARTUPINFO si;
	ZeroMemory(reinterpret_cast<void*> (&si),sizeof(si));
	si.cb=sizeof(si);
	
	PROCESS_INFORMATION pi;
	
	BOOL bCreateOK=CreateProcess(
		szFilename,
		szCmdLine,
		NULL,
		NULL,
		FALSE,
		0, //CREATE_NEW_CONSOLE 使得进程各自print时分开 
		NULL,
		NULL,
		&si,
		&pi);
	if(bCreateOK)
	{
		CloseHandle(pi.hProcess);
		CloseHandle(pi.hThread); 
	}
	return(bCreateOK);
}
void Produce()
{
	HANDLE hMapping=OpenFileMapping(FILE_MAP_ALL_ACCESS,FALSE,filemapping_name);
	HANDLE hMutex_write=OpenMutex(MUTEX_ALL_ACCESS,FALSE,mutex_write_name);
	HANDLE hMutex_print=OpenMutex(MUTEX_ALL_ACCESS,FALSE,mutex_print_name);
	HANDLE hSem_full=OpenSemaphore(SEMAPHORE_ALL_ACCESS,FALSE,sem_full);
	HANDLE hSem_empty=OpenSemaphore(SEMAPHORE_ALL_ACCESS,FALSE,sem_empty);
	HANDLE hEventContinue=OpenEvent(EVENT_MODIFY_STATE,FALSE,event_continue_name);
	
	LPVOID pFile=MapViewOfFile(
		hMapping,
		FILE_MAP_ALL_ACCESS,
		0,
		0,
		0//映射整个文件
	); 	
	if(pFile==NULL)	
	{
		return;
		printf("producer die!!\n");
	}
	
	CHAR** ppData=reinterpret_cast<CHAR**> (pFile+4);  
	struct timeval t;
	unsigned int seed;
	int count=4;
	WaitForSingleObject(hEventContinue,INFINITE);
	while(count--)
	{
		gettimeofday(&t,NULL);
		seed=t.tv_usec;
		srand(seed);
		int time=rand()%2000;
		Sleep(time);
		
		WaitForSingleObject(hSem_empty,INFINITE);//是否还有空位 
		WaitForSingleObject(hMutex_write,INFINITE);//互斥访问共享内存

		WaitForSingleObject(hMutex_print,INFINITE);
		printf("produce:%c %ld\n",a[time%3],*ppData);
		**ppData=a[time%3];
		printf("buffer: %c %c %c %c \n\n",*(char*)(pFile),*(char*)(pFile+1),*(char*)(pFile+2),*(char*)(pFile+3));
		ReleaseMutex(hMutex_print);
		
		if(*ppData==pFile+3) //一个环形缓冲区
		{
			*ppData=(CHAR*)pFile;
			
		}	
		else
			++(*ppData); 

		ReleaseMutex(hMutex_write);
		ReleaseSemaphore(hSem_full,1,NULL);//full信号量+1
	} 
	UnmapViewOfFile(pFile);
	CloseHandle(hMapping);
	CloseHandle(hMutex_write);
	CloseHandle(hMutex_print);
	CloseHandle(hSem_full);
	CloseHandle(hSem_empty);
	CloseHandle(hEventContinue);
}

void Consume()
{
	HANDLE hMapping=OpenFileMapping(FILE_MAP_ALL_ACCESS,FALSE,filemapping_name);
	HANDLE hMutex_read=OpenMutex(MUTEX_ALL_ACCESS,FALSE,mutex_read_name);
	HANDLE hMutex_print=OpenMutex(MUTEX_ALL_ACCESS,FALSE,mutex_print_name);
	HANDLE hSem_full=OpenSemaphore(SEMAPHORE_ALL_ACCESS,FALSE,sem_full);
	HANDLE hSem_empty=OpenSemaphore(SEMAPHORE_ALL_ACCESS,FALSE,sem_empty);
	HANDLE hEventContinue=OpenEvent(EVENT_MODIFY_STATE,FALSE,event_continue_name);
	
	LPVOID pFile=MapViewOfFile(
		hMapping,
		FILE_MAP_ALL_ACCESS,
		0,
		0,
		0//映射整个文件
	); 
	if(pFile==NULL)	
	{
		return;
		printf("consumer die!!\n");
	}
	
	CHAR** ppData=reinterpret_cast<CHAR**> (pFile+12); 
	struct timeval t;
	unsigned int seed;
	int count=3;
	WaitForSingleObject(hEventContinue,INFINITE);
	while(count--)
	{
		gettimeofday(&t,NULL);
		seed=t.tv_usec;
		srand(seed);
		int time=rand()%3000;
		Sleep(time);
		
		WaitForSingleObject(hSem_full,INFINITE);//是否有数据 
		WaitForSingleObject(hMutex_read,INFINITE);//互斥访问共享内存
		
		WaitForSingleObject(hMutex_print,INFINITE);
		printf("consume:%c %ld\n",**ppData,*ppData);
		**ppData='-';
		printf("buffer: %c %c %c %c \n\n",*(char*)(pFile),*(char*)(pFile+1),*(char*)(pFile+2),*(char*)(pFile+3));
		ReleaseMutex(hMutex_print);

		if(*ppData==pFile+3) 
			*ppData=(CHAR*)pFile;
		else
			++(*ppData);
			
		ReleaseMutex(hMutex_read);
		ReleaseSemaphore(hSem_empty,1,NULL);//full信号量+1
		
	} 
	UnmapViewOfFile(pFile);
	CloseHandle(hMapping);
	CloseHandle(hMutex_read);
	CloseHandle(hMutex_print);
	CloseHandle(hSem_full);
	CloseHandle(hSem_empty);
	CloseHandle(hEventContinue);
}
void Init_Wait()
{
	HANDLE hMapping=CreateFileMapping(
		INVALID_HANDLE_VALUE,//使用页式临时文件
		NULL,
		PAGE_READWRITE,
		0,
		28,//4+8+8+4+4
		filemapping_name);
	HANDLE hSem_full=CreateSemaphore(
		NULL,//默认安全属性 
		0,//信号量初值
		4,//允许4个进程/线程同时访问 也是信号量的最大值 
		sem_full);
	HANDLE hSem_empty=CreateSemaphore(
		NULL,//默认安全属性 
		4,//信号量初值
		4,//允许一个进程/线程访问
		sem_empty);
	HANDLE mutex_read=CreateMutex(
		NULL,
		TRUE,//当前进程获得互斥锁
		mutex_read_name);
	HANDLE mutex_write=CreateMutex(
		NULL,
		TRUE,//当前进程获得互斥锁
		mutex_write_name);
	HANDLE mutex_print=CreateMutex(
		NULL,
		TRUE,//当前进程获得互斥锁
		mutex_print_name);
	HANDLE hEventContinue=CreateEvent(
		NULL,
		TRUE,//人工重置事件 
		FALSE,//初始为 无信号状态 
		event_continue_name);
	LPVOID pFile=MapViewOfFile(
		hMapping,
		FILE_MAP_ALL_ACCESS,
		0,
		0,
		0//映射整个文件
	); 
	
	CHAR** ppData_w=reinterpret_cast<CHAR**> (pFile+4);
	CHAR** ppData_r=reinterpret_cast<CHAR**> (pFile+12);
	CHAR* pBase= reinterpret_cast<CHAR*> (pFile);
	memset(pBase,'-',4*sizeof(char));

	*ppData_w=*ppData_r=(CHAR*) pFile;
	
	for(int i=0;i<3;i++)//3生产者
	{
		CreateChild("producer\0");
	} 
	for(int i=0;i<4;i++)
	{
		CreateChild("consumer\0");
	}
	ReleaseMutex(mutex_print);
	ReleaseMutex(mutex_read);
	ReleaseMutex(mutex_write);
	SignalStart();
	Sleep(10000); 
}


int main(int argc,char* argv[])
{
	if(argc>1&&strcmp(argv[1],"producer")==0){
		Produce();
	}
	else if(argc>1&&strcmp(argv[1],"consumer")==0) 
	{
		Consume();
	}
	else
	{
		Init_Wait();
	}
}

  • 1
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 7
    评论
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

mrbone11

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值