共享内存在winodws操作系统下的使用
2014-10-24 14:02
148 查看
共享内存在winodws操作系统下的使用
本文转自:http://lmf025.blog.163.com/blog/static/573873802008313114910319/
共享内存的使用
在Windows操作系统下,任何一个进程不允许读取、写入或是修改另一个进程的数据(包括变量、对象和内存分配等),但是在某个进程内创建的文件映射对象的视图却能够为多个其他进程所映射,这些进程共享的是物理存储器的同一个页面。因此,当一个进程将数据写入此共享文件映射对象的视图时,其他进程可以立即获取数据变更情况。为了进一步提高数据交换的速度,还可以采用由系统页文件支持的内存映射文件而直接在内存区域使用,显然这种共享内存的方式是完全可以满足在进程间进行大数据量数据快速传输任务要求的。下面给出在两个相互独立的进程间通过文件映射对象来分配和访问同一个共享内存块的应用实例。在本例中,由发送方程序负责向接收方程序发送数据,文件映射对象由发送方创建和关闭,并且指定一个唯一的名字供接收程序使用。接收方程序直接通过这个唯一指定的名字打开此文件映射对象,并完成对数据的接收。
在发送方程序中,首先通过CreateFileMapping()函数创建一个内存映射文件对象,如果创建成功则通过MapViewOfFile()函数将此文件映射对象的视图映射进地址空间,同时得到此映射视图的首址。可见,共享内存的创建主要是通过这两个函数完成的。这两个函数原形声明如下:
HANDLE CreateFileMapping(HANDLE hFile, LPSECURITY_ATTRIBUTES lpFileMappingAttributes, DWORD flProtect, DWORD dwMaximumSizeHigh, DWORD dwMaximumSizeLow, LPCTSTR lpName); LPVOID MapViewOfFile(HANDLE hFileMappingObject, DWORD dwDesiredAccess, DWORD dwFileOffsetHigh, DWORD dwFileOffsetLow, DWORD dwNumberOfBytesToMap); |
hRecvMap = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE | SEC_COMMIT, 0, 1000000, "DataMap"); if (hRecvMap != NULL) { lpData = (LPBYTE)MapViewOfFile(hRecvMap, FILE_MAP_WRITE, 0, 0, 0); if (lpData == NULL) { CloseHandle(hRecvMap); hRecvMap = NULL; } } // 通知接收程序内存文件映射对象的视图已经打开 HWND hRecv = ::FindWindow(NULL, DECODE_PROGRAMM); if (hRecv != NULL) ::PostMessage(hRecv, WM_MAP_OPEN, 0, 0); |
// 数据复制到共享内存 memcpy(lpData, RecvBuf, sizeof(RecvBuf)); // 通知接收方接收数据 HWND hDeCode = ::FindWindow(NULL, DECODE_PROGRAMM); if (hDeCode != NULL) ::PostMessage(hDeCode, WM_DATA_READY, (WPARAM)0, (LPARAM)sizeof(RecvBuf)); |
HWND hDeCode = ::FindWindow(NULL, DECODE_PROGRAMM); if (hDeCode != NULL) ::PostMessage(hDeCode, WM_MAP_CLOSE, 0, 0); if (lpData != NULL) { UnmapViewOfFile(lpData); lpData = NULL; } if (hRecvMap != NULL) { CloseHandle(hRecvMap); hRecvMap = NULL; } |
m_hReceiveMap = OpenFileMapping(FILE_MAP_READ, FALSE, "DataMap"); if (m_hReceiveMap == NULL) return; m_lpbReceiveBuf = (LPBYTE)MapViewOfFile(m_hReceiveMap,FILE_MAP_READ,0,0,0); if (m_lpbReceiveBuf == NULL) { CloseHandle(m_hReceiveMap); m_hReceiveMap=NULL; } |
// 从共享内存接收数据 memcpy(RecvBuf, (char*)(m_lpbReceiveBuf), (int)lParam); …… // 程序退出前资源的释放 UnmapViewOfFile(m_lpbReceiveBuf); m_lpbReceiveBuf = NULL; CloseHandle(m_hReceiveMap); m_hReceiveMap = NULL; |
HANDLE hSem = OpenSemaphore( SEMAPHORE_ALL_ACCESS ,FALSE, "my_mutex");
if (!hSem)
{
hSem = CreateSemaphore(NULL, 1, 1, "my_mutex");
if (hSem == INVALID_HANDLE_VALUE)
{
return false;
}
}
DWORD ret = WaitForSingleObject(hSem, 5000);
if (ret == WAIT_OBJECT_0)
{
Sleep(100000);
}
ReleaseSemaphore(hSem, 1, NULL);
CloseHandle(hSem);
小结
经实际测试,使用共享内存在处理大数据量数据的快速交换时表现出了良好的性能,在数据可靠性等方面要远远高于发送WM_COPYDATA消息的方式。这种大容量、高速的数据共享处理方式在设计高速数传通讯类软件中有着很好的使用效果。本文所述代码在Windows 2000下由Microsoft Visual C++ 6.0编译通过。
相关文章推荐
- 共享内存在winodws操作系统下的使用
- 共享内存的使用
- 共享内存 shm*库 使用流程
- 32位操作系统下利用Ramdisk使用Unmanaged内存
- Windows Mobile使用Shared Memory(共享内存)进行IPC(进程间通信)的开发
- linux下共享内存(shm)使用示例
- [转]PHP之中使用共享内存进行高速数据更新的一种方案
- 使用多个第三方类库的问题(DLL内存分配与共享)
- 使用DLL在进程间共享内存_如何在多进程中用共享DLL
- 在FreeBSD 用户空间与内核空间使用内存共享
- 进程之间使用共享内存通信....
- 【共享】在windows操作系统上同时使用IE6和IE7
- eaccelerator 应用之“使用共享内存存储Session”
- 使用内存共享机制进程间通讯
- 共享内存区一定要使用偏移量,而非指针!
- 使用技巧:共享内存在Java中实现和应用
- php之中使用共享内存进行高速数据更新的一种方案
- 用SQL 查找操作系统内存使用情况
- MySQL内存使用 - 全局共享
- 使用shm_open来操作共享内存