用文件映射(File Mapping)实现进程间内存共享
2010-11-15 16:12
411 查看
我们知道,在Windows中的每个进程都有自己独立的内存空间。该独立的内存空间包含了所有的可执行模块或DLL模块的代码和数据以及动态内存分配的空间。每个进程的内存空间只能被该进程访问,其他进程是不能访问的。
如果我们要想在进程间共享内存(也就是创建一块不同进程都能访问的内存),那就必须使用内核对象。因为内核对象由Windows系统内核所拥有,而不是由进程所拥有。
下面就用文件映射(File Mapping)和互斥量(Mutex)两中内核对象来实现简单的进程间内存共享。文件映射(File Mapping)用来开辟共享的内存空间,而互斥量(Mutex)则是用来使读写互斥。
在该例子里,实现了下面5个函数用来进行进程间的内存共享。可以把这5个函数放到一个DLL里面当成输出函数来用。在进程里加载该DLL并调用相应的函数就可实现进程间内存共享。
首先,定义返回值代码:
下面是函数的实现:
// 自动Lock和Unlock互斥量
如果我们要想在进程间共享内存(也就是创建一块不同进程都能访问的内存),那就必须使用内核对象。因为内核对象由Windows系统内核所拥有,而不是由进程所拥有。
下面就用文件映射(File Mapping)和互斥量(Mutex)两中内核对象来实现简单的进程间内存共享。文件映射(File Mapping)用来开辟共享的内存空间,而互斥量(Mutex)则是用来使读写互斥。
在该例子里,实现了下面5个函数用来进行进程间的内存共享。可以把这5个函数放到一个DLL里面当成输出函数来用。在进程里加载该DLL并调用相应的函数就可实现进程间内存共享。
首先,定义返回值代码:
typedef enum { LX_OK = 0, // 正常返回 LX_SHAREDMEMORY_EXISTS = 1, // 共享内存已经存在 LX_INVALID_SHAREDMEMORY = 2, // 共享内存错误返回 LX_INVALID_SIZE = 3 // 共享内存大小错误 }LX_RETURN_VALUE;然后,是函数声明:
// 创建共享内存 LX_RETURN_VALUE CreateSharedMemory(UINT nSize); // 释放共享内存 LX_RETURN_VALUE ReleaseSharedMemory(); // 得到共享内存大小 LX_RETURN_VALUE GetSharedMemorySize(UINT& nSize); // 向共享内存写入数据 LX_RETURN_VALUE WriteToSharedMemory(void *pData, UINT nSize); // 从共享内存读取数据 LX_RETURN_VALUE ReadFromSharedMemory(void *pData, UINT nSize);
下面是函数的实现:
// 自动Lock和Unlock互斥量
struct CAutoMutex { CAutoMutex(); ~CAutoMutex(); // 互斥量 static CMutex m_mutex; }; CMutex CAutoMutex::m_mutex(FALSE, "StarLeeMutex"); CAutoMutex::CAutoMutex() { m_mutex.Lock(); } CAutoMutex::~CAutoMutex() { m_mutex.Unlock(); }
LX_RETURN_VALUE CreateSharedMemory(UINT nSize) { // 创建共享内存块 HANDLE hFileMapping = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, nSize, "StarLeeSharedMemory"); // 创建错误 if ((hFileMapping == NULL) || (hFileMapping == INVALID_HANDLE_VALUE)) return LX_INVALID_SHAREDMEMORY; // 共享内存已经存在 if (GetLastError() == ERROR_ALREADY_EXISTS) return LX_SHAREDMEMORY_EXISTS; // 创建另外一块内存存放共享内存的大小 HANDLE hSize = CreateFileMapping(NULL, NULL, PAGE_READWRITE, 0, sizeof(UINT), "StarLeeSharedMemorySize"); if ((hSize == NULL) || (hSize == INVALID_HANDLE_VALUE) || (GetLastError() == ERROR_ALREADY_EXISTS)) return LX_INVALID_SHAREDMEMORY; // 得到存放共享内存大小的指针 UINT *pSize = (UINT *)MapViewOfFile(hSize, FILE_MAP_WRITE, 0, 0, sizeof(UINT)); if (pSize == NULL) return LX_INVALID_SHAREDMEMORY; // 写入共享内存的大小 memcpy(pSize, &nSize, sizeof(UINT)); UnmapViewOfFile(pSize); return LX_OK; }
LX_RETURN_VALUE ReleaseSharedMemory() { CAutoMutex MutexLock; // 打开共享内存 HANDLE hFileMapping = OpenFileMapping(FILE_MAP_ALL_ACCESS, FALSE, "StarLeeSharedMemory"); // 关闭共享内存 if (hFileMapping != NULL) CloseHandle(hFileMapping); // 打开存放共享内存大小的文件映射 HANDLE hSize = OpenFileMapping(FILE_MAP_ALL_ACCESS, FALSE, "StarLeeSharedMemorySize"); // 关闭存放共享内存大小的文件映射 if (hSize != NULL) CloseHandle(hSize); return LX_OK; }
LX_RETURN_VALUE GetSharedMemorySize(UINT& nSize) { CAutoMutex MutexLock; HANDLE hSize = OpenFileMapping(FILE_MAP_READ, FALSE, "StarLeeSharedMemorySize"); if (hSize == NULL) return LX_INVALID_SHAREDMEMORY; UINT *pSize = (UINT *)MapViewOfFile(hSize, FILE_MAP_READ, 0, 0, sizeof(UINT)); if (pSize == NULL) return LX_INVALID_SHAREDMEMORY; // 得到共享内存的大小 memcpy(&nSize, pSize, sizeof(UINT)); return LX_OK; }
LX_RETURN_VALUE WriteToSharedMemory(void *pDate, UINT nSize) { UINT nSharedMemorySize = 0; // 得到共享内存的大小 if (GetSharedMemorySize(nSharedMemorySize) != LX_OK) return LX_INVALID_SHAREDMEMORY; // 检查共享内存的大小 if (nSize > nSharedMemorySize) return LX_INVALID_SIZE; CAutoMutex MutexLock; HANDLE hFileMapping = OpenFileMapping(FILE_MAP_WRITE, FALSE, "StarLeeSharedMemory"); if (hFileMapping == NULL) return LX_INVALID_SHAREDMEMORY; void *pMapView = MapViewOfFile(hFileMapping, FILE_MAP_WRITE, 0, 0, nSize); if (pMapView == NULL) return LX_INVALID_SHAREDMEMORY; // 清空共享内存 memset(pMapView, 0, nSharedMemorySize); // 将数据写入共享内存 memcpy(pMapView, pDate, nSize); UnmapViewOfFile(pMapView); return LX_OK; }
LX_RETURN_VALUE ReadFromSharedMemory(void *pData, UINT nSize) { UINT nSharedMemorySize = 0; if (GetSharedMemorySize(nSharedMemorySize) != LX_OK) return LX_INVALID_SHAREDMEMORY; if (nSize > nSharedMemorySize) return LX_INVALID_SIZE; CAutoMutex MutexLock; HANDLE hFileMapping = OpenFileMapping(FILE_MAP_READ, FALSE, "StarLeeSharedMemory"); if (hFileMapping == NULL) return LX_INVALID_SHAREDMEMORY; void *pMapView = MapViewOfFile(hFileMapping, FILE_MAP_READ, 0, 0, nSize); if (pMapView == NULL) return LX_INVALID_SHAREDMEMORY; // 从共享内存读取数据 memcpy(pData, pMapView, nSize); UnmapViewOfFile(pMapView); return LX_OK; }转载:http://blog.csdn.net/starlee/archive/2007/06/01/1633762.aspx
相关文章推荐
- 用文件映射(File Mapping)实现进程间内存共享
- 用文件映射(File Mapping)实现进程间内存共享
- 用文件映射(File Mapping)实现进程间内存共享[转]
- 用文件映射(File Mapping)实现进程间内存共享
- 用文件映射(File Mapping)实现进程间内存共享
- 用文件映射(File Mapping)实现进程间内存共享
- 通过内存映射文件实现进程间数据共享
- UNIX环境高级编程学习之第十五章进程间通信 - 两个进程通过映射普通文件实现共享内存通信
- c++ 内存映射文件进程间共享数据
- 内存映射文件进程间共享内存
- 利用内存映射文件在两个进程间共享数据 转
- C# .Net 多进程同步 通信 共享内存 内存映射文件 Memory Mapped
- windows下利用文件映射实现共享内存
- 使用内存映射文件在进程之间共享数据
- Linux\Unix IPC进程通信实例分析(一):共享内存通信---文件映射mmap方式
- 利用内存映射文件在进程间共享数据
- 用内存映射文件在进程中共享数据
- windows下利用文件映射实现共享内存
- mmap映射文件至内存( 实现 共享内存 与 文件的另类访问 )
- C# .Net 多进程同步 通信 共享内存 内存映射文件 Memory Mapped