共享内存加锁互斥访问

在做项目时遇到需要用到多个进程对共享内存读写,考虑到数据冲突问题,特加上互斥作为访问约束条件,具体代码如下:

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;
}

  • 2
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值