进程同步(读写共享内存)



进程同步(读写共享内存)

一、简介

       本文展示了如何使用Win32事件来解决多个读、写线程的同步问题。在编译了源码之后,你会得到作为读、写共享内存而存在的控制台应用程序。同时可以执行多个程序用于测试。但是某一时刻只允许一个程序执行写操作。如果某一个写操作在执行,那么其他读、写程序都会被阻塞。然而,多个读操作可以同时运行。如果读操作正在执行,那么写操作只有在所有读操作完成之后才能处理。这种同步机制确保了读写操作正确同步、避免任意时刻的数据冲突。

二、源码分析

       源码中包含了读写操作使用的共享内存,使用事件机制来实现同步功能。

下面是初始化事件和共享内存的代码:

//初始化事件对象和共享内存对象
bool Initialize()
{
	char szBuffer[32];
	for(int i=0; i<MAX_READ_PROCESSES_ALLOWED; i++)
	{
		sprintf_s(szBuffer, "Reader_%d", i);
		//创建读事件
		g_hReadEvent[i] = CreateEvent(NULL, false, true, szBuffer);
		if(NULL == g_hReadEvent[i])
			return false;
	}

	//创建写事件 
	g_hWriteEvent = CreateEvent(NULL, false, true, g_szWriteName);
	if(NULL == g_hWriteEvent)
		return false;

	//创建共享内存缓冲区
	g_hShareMemory = CreateFileMapping(INVALID_HANDLE_VALUE, 
		NULL, PAGE_READWRITE, 0, MAX_SHARE_MEM_SIZE, g_szShareMemoryName);

	if(NULL==g_hShareMemory || INVALID_HANDLE_VALUE==g_hShareMemory)
	{
		printf("Error occured shile creating file mapping object\n");
		return false;
	}

	g_pBuffer = (LPTSTR)MapViewOfFile(g_hShareMemory, FILE_MAP_ALL_ACCESS, 0, 0, MAX_SHARE_MEM_SIZE);
	if(NULL == g_pBuffer)
	{
		printf("Error occured while mapping view of the file\n");
		return false;
	}

	return true;
}

void ReadAndPrint()
{
	printf("从共享内存中读取数据并打印...\n");
	//等待所有的写操作结束,数据已经同步
	bool bContinue = true;
	while(bContinue)
	{
		printf("等待写操作完成...、\n");
		DWORD dwWaitResult = WaitForSingleObject(g_hWriteEvent, INFINITE);
		if(WAIT_OBJECT_0 == dwWaitResult)
		{
			bool bEventFount = false;
			for(int i=0; i<MAX_READ_PROCESSES_ALLOWED; i++)
			{
				DWORD dwWaitResult = WaitForSingleObject(g_hReadEvent, WAIT_TIMEOUT);
				if(WAIT_OBJECT_0 == dwWaitResult)
				{
					bEventFount = true;
					printf("设置写事件...\n");
					SetEvent(g_hWriteEvent);
					//读共享内存
					printf("共享内存中内容是:%s\n", g_pBuffer);
					printf("设置读事件...\n");
					SetEvent(g_hReadEvent[i]);

					bContinue = false;
					break;
				}
				else
				{
					continue;
				}
			}
		}
		else
		{
			printf("等待出错:%d\n", GetLastError());
		}
	}
}

//写函数使用事件来同步
void WriteAndPrint()
{
	printf("写人并输出共享内存数据...\n");
	printf("等待写操作结束...\n");

	if(WAIT_OBJECT_0 == WaitForSingleObject(g_hWriteEvent, INFINITE))
	{
		printf("等待所有读操作结束...\n");
		DWORD dwWaitResult = WaitForMultipleObjects(MAX_READ_PROCESSES_ALLOWED, 
			g_hReadEvent, TRUE, INFINITE);

		if(WAIT_OBJECT_0 == dwWaitResult)
		{
			printf("输入字符串:(不要空格):");
			printf("%s", g_pBuffer);
			printf("共享内存数据:%s", g_pBuffer);
		}
		else
		{
			printf("等待出错:%d", GetLastError());
		}

		printf("设置写事件...\n");
		SetEvent(g_hWriteEvent);
		printf("设置读事件...\n");
		for(int i=0; i<MAX_READ_PROCESSES_ALLOWED; i++)
		{
			SetEvent(g_hReadEvent[i]);
		}
	}
	else
	{
		printf("deng\n");
	}
}

void DdeInitialize()
{
	for(int i=0; i< MAX_READ_PROCESSES_ALLOWED; i++)
	{
		CloseHandle(g_hReadEvent[i]);
	}

	CloseHandle(g_hWriteEvent);
	UnmapViewOfFile(g_pBuffer);
	CloseHandle(g_hShareMemory);
}

int _tmain(int argc, _TCHAR* argv[])
{
	if (Initialize())
     {
          ...
     }
     else
     {
         ...
     }
     
     bool bContinue = true;
     
     while(bContinue)
     {
          DisplayOptions();
          bContinue = RecvAndProcessOption();
     }
     
     DeInitialize();
     
     return 0; //success
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值