在做项目时遇到需要用到多个进程对共享内存读写,考虑到数据冲突问题,特加上互斥作为访问约束条件,具体代码如下:
HANDLE CreateOpenFileMapping(LPCTSTR lpShareMemName)
{
//打开共享的文件对象。
HANDLE hMapFile = OpenFileMapping(FILE_MAP_ALL_ACCESS, FALSE,lpShareMemName);
if (hMapFile)
{
}
else
{
//创建共享文件。
hMapFile = CreateFileMapping(INVALID_HANDLE_VALUE,NULL, PAGE_READWRITE,0,BUF_SIZE,lpShareMemName);
}
return hMapFile;
}
//向共享内存写入数据
/
///函数主要对共享内存读写
///hMapFile :共享内训映射句柄
///bInOutData:写入或者读取数据
///lpMutexName:互斥量名字
///bRW :读写标志 0 read ; 1 write
///返回值 ture成功 ;false 失败
/
BOOL OperateData(HANDLE hMapFile,BYTE *bInOutData,LPCTSTR lpMutexName,bool bRW)
{
BOOL bSuc = FALSE;
BYTE *pBuf = (BYTE *)MapViewOfFile(
hMapFile, // 共享内存的句柄
FILE_MAP_ALL_ACCESS, // 可读写许可
0,
0,
BUF_SIZE
);
if (pBuf)
{
//加把锁在这地方
HANDLE hMutex = CreateMutex(NULL,FALSE,lpMutexName);
if (hMutex && WaitForSingleObject(hMutex, 30*1000) == WAIT_OBJECT_0)
{
if (bRW)
{
memset(pBuf,0,BUF_SIZE);
memcpy(pBuf,bInOutData,BUF_SIZE - 1);
}
else
{
memcpy(bInOutData,pBuf,BUF_SIZE - 1);
}
ReleaseMutex(hMutex);
CloseHandle(hMutex);
UnmapViewOfFile(pBuf);
hMutex = NULL;
pBuf = NULL;
bSuc = TRUE;
}
}
return bSuc;
}
//读取共享内存数据
BOOL ReadFromMen(HANDLE hMapFile,BYTE *bOutData,LPCTSTR lpMutexName)
{
BOOL bSuc = FALSE;
BYTE *pBuf = (BYTE *)MapViewOfFile(
hMapFile, // 共享内存的句柄
FILE_MAP_ALL_ACCESS, // 可读写许可
0,
0,
BUF_SIZE
);
if (pBuf)
{
//加把锁在这地方
HANDLE hMutex = CreateMutex(NULL,FALSE,lpMutexName);
if (hMutex && WaitForSingleObject(hMutex, 30*1000) == WAIT_OBJECT_0)
{
ReleaseMutex(hMutex);
CloseHandle(hMutex);
UnmapViewOfFile(pBuf);
hMutex = NULL;
pBuf = NULL;
bSuc = TRUE;
}
}
return bSuc;
}
wchar_t *MultToWide(LPSTR pChar)
{
wchar_t* pWCHAR=NULL;
//计算pChar所指向的多字节字符串相当于多少个宽字节
DWORD num=MultiByteToWideChar(CP_ACP,0,pChar,-1,NULL,0);
pWCHAR=(wchar_t*)malloc(num*sizeof(wchar_t));
if (pWCHAR==NULL)
{
free(pWCHAR);
}
memset(pWCHAR,0,num*sizeof(wchar_t));
//多字节转换为宽字节
MultiByteToWideChar(CP_ACP,0,pChar,-1,pWCHAR,num);
return pWCHAR;
}
char *WideToMult(LPWSTR pWCHAR)
{
//计算需要多少个字节才能表示对应的多字节字符串
DWORD num=WideCharToMultiByte(CP_ACP,0,pWCHAR,-1,NULL,0,NULL,0);
//开辟空间
char *pChar=NULL;
pChar=(char*)malloc(num*sizeof(char));
if (pChar)
{
memset(pChar,0,num*sizeof(char));
//将宽字节字符串转换为多字节字符串
WideCharToMultiByte(CP_ACP,0,pWCHAR,-1,pChar,num,NULL,0);
}
return pChar;
}
int _tmain()
{
创建共享文件句柄
//HANDLE hMapFile = CreateFileMapping(
// INVALID_HANDLE_VALUE, // 物理文件句柄
// NULL, // 默认安全级别
// PAGE_READWRITE, // 可读可写
// 0, // 高位文件大小
// BUF_SIZE, // 地位文件大小
// szName // 共享内存名称
// );
//char *pBuf = (char *)MapViewOfFile(
// hMapFile, // 共享内存的句柄
// FILE_MAP_ALL_ACCESS, // 可读写许可
// 0,
// 0,
// BUF_SIZE
// );
//while(1)
//{
// cout << "input..." << endl;
// char szInfo[BUF_SIZE] = {0};
// gets(szInfo); // 其实gets并不安全
// strncpy(pBuf, szInfo, BUF_SIZE - 1);
// pBuf[BUF_SIZE - 1] = '\0';
//}
//UnmapViewOfFile(pBuf);
//CloseHandle(hMapFile);
//写入
HANDLE hMapFile = CreateOpenFileMapping(_T("NameOfMappingObject"));
for (int i=0;i<1000000;i++)
{
CString strInput = _T("");
strInput.Format(_T("%d%d%d%d%d%d;"),i,i,i,i,i,i);
char *bInOutData = WideToMult(strInput.GetBuffer(NULL));
BOOL Suc = OperateData(hMapFile,(BYTE*)bInOutData,_T("NameOfMappingObjectMutex"),1);
cout<<bInOutData<<endl;
delete []bInOutData;
bInOutData = NULL;
}
//读取数据
//for (int i=1;i>0;i++)
//{
// HANDLE hMapFile1 = CreateOpenFileMapping(_T("NameOfMappingObject"));
// BYTE bOutData[1024];
// BOOL Suc = OperateData(hMapFile1,(BYTE*)bOutData,_T("NameOfMappingObjectMutex"),0);
// char *P = (char*)bOutData;
// cout<<P<<endl;
// wchar_t *pWchar = MultToWide(P);
// CString strOut = pWchar;
// delete []pWchar;
// pWchar = NULL;
// Sleep(100);
//}
return 0;
}