进程同步(读写共享内存)
一、简介
本文展示了如何使用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
}