Windows核心编程之共享内存

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 
#include 
#include 
using namespace std;

#ifdef _UNICODE
#define tstring wstring
#else
#define tstring string
#endif

UINT _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 
#include 
#include 
using namespace std;

#ifdef _UNICODE
#define tstring wstring
#else
#define tstring string
#endif

UINT _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

 

你可能感兴趣的:(Windows)