Windows核心编程之共享内存

来源:互联网 发布:olay博研诗 知乎 编辑:程序博客网 时间:2024/05/18 01:17

Windows共享数据和信息的机制:RPC、COM、OLE、DDE、窗口消息、剪贴板、邮箱、管道、套接字以及内存映射文件。

内存映射:通过让两个或多个进程映射同一个文件。(在进程空间中保留一个地址空间区域,将物理存储器提交给该区域)

内存映射文件的物理存储器(用来作为虚拟内存)来自一个位于磁盘驱动器上的数据文件。一旦该文件被映射,就可以访问它,就像文件已经加载内存一样。(操作系统使得内存能够将一个数据文件映射到进程的地址空间中)

CreateFile //创建或打开文件内核对象

CreateFileMapping //创建文件映射内核对象(OpenFileMapping,在其它进程中,打开文件映射对象)

MapViewOfFile //将文件数据映射到进程的地址空间

UnmapViewOfFile //从进程的地址空间撤销文件数据的映像

CloseHandle //关闭文件对象和文件映射对象


同时为了方便进程间数据共享,Microsoft提供了基于页文件的内存映射文件

与创建内存映射磁盘文件基本相同,但是不必调用CreateFile,因为不是创建或打开指定的文件。只需要像通常那样调用CreateFileMapping函数:

HANDLE WINAPI CreateFileMapping(

HANDLE hFile,
LPSECURITY_ATTRIBUTESlpAttributes,
DWORD lProtect,
DWORD dwMaximumSizeHigh,
DWORD dwMaximumSizeLow,
LPCTSTR lpName
);

传递INVALID_HANDLE_VALUE作为hFile的参数,这是告诉系统:这不是创建驻留在磁盘上的文件的映射对象,而是从系统的页文件中提交物理存储器。

且分配的存储器的大小由dwMaximumSizeHigh和dwMaximumSizeLow两个函数来决定。



共享内存的写入端程序(同时创建了带原子操作的线程来观察内存间Interlocked系列的原子操作是否有效)

#include <Windows.h>#include <process.h>#include <string>using namespace std;#ifdef _UNICODE#define tstring wstring#else#define tstring string#endifUINT _stdcall writeFunc(void *pvContext){//InterlockedIncrement((long*)pvContext);InterlockedExchangeAdd((long*)pvContext, 1);return 0;}int _tmain(int argc, _TCHAR* argv[]){tstring mapName = _T("sharememory");//多进程想指向同一内存块,共享内存名称必须相同INT *pCount = NULL;HANDLE threadHandle;HANDLE hMapMem;hMapMem = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, 4, mapName.c_str());if (hMapMem == NULL){printf("创建共享内存失败\n");}else{pCount = (INT*)MapViewOfFile(hMapMem, FILE_MAP_ALL_ACCESS, 0, 0, 0);*pCount = 0;//先开启共享写入进程//如果想观察线程间互斥效果,请在此时打开读取进程,然后在继续getchar();for (INT index = 0; index < 1000; index++){threadHandle = (HANDLE)_beginthreadex(NULL, 0, writeFunc, (void*)pCount, 0, NULL);if (threadHandle){WaitForSingleObject(threadHandle, INFINITE);printf("写入共享文件内存%d\n", *pCount);CloseHandle(threadHandle);}}fflush(stdin);//刷新标准输入流getchar();printf("写入共享文件内存%d\n", *pCount);UnmapViewOfFile(pCount);CloseHandle(hMapMem);}system("pause");return 0;}


共享内存的读取端程序

#include <Windows.h>#include <process.h>#include <string>using namespace std;#ifdef _UNICODE#define tstring wstring#else#define tstring string#endifUINT _stdcall readFunc(void *pvContext){//InterlockedDecrement((long*)pvContext);InterlockedExchangeAdd((long*)pvContext, -1);return 0;}int _tmain(int argc, _TCHAR* argv[]){tstring mapName = _T("sharememory");INT *pCount = NULL;HANDLE threadHandle;HANDLE hMapMem;hMapMem = OpenFileMapping(FILE_MAP_ALL_ACCESS, FALSE, mapName.c_str());if (hMapMem == NULL){printf("打开共享内存失败\n");}else{pCount = (INT*)MapViewOfFile(hMapMem, FILE_MAP_ALL_ACCESS, 0, 0, 0);while ((*pCount) == 0){Sleep(0);//放弃当前CPU时间片}for (INT index = 0; index < 1000; index++){threadHandle = (HANDLE)_beginthreadex(NULL, 0, readFunc, (void*)pCount, 0, NULL);if (threadHandle){WaitForSingleObject(threadHandle, INFINITE);printf("读取共享文件内存%d\n", *pCount);CloseHandle(threadHandle);}}getchar();printf("读取共享文件内存%d\n", *pCount);UnmapViewOfFile(pCount);CloseHandle(hMapMem);}system("pause");return 0;}



Windows共享内存示例 http://www.cnblogs.com/dongsheng/p/4460944.html


0 0
原创粉丝点击