我需要传输一些数据 – char buffer[100000];
– 由我开始的一个孩subprocess。
现在我正在使用一个普通的文件来这样做,父进程将数据写入磁盘上的一个文件,subprocess从磁盘读取并删除文件。 但是,这会导致不必要的写入磁盘,所以我想使用内存映射文件。
除非使用页面文件或交换文件,否则如何创build,写入,然后从内存映射文件中读取数据,以便不将数据写入磁盘?
编辑:我忘了指定,我想使用原始的WINAPI函数,所以代码没有依赖关系。 我正在研究如何做到这一点,准备好后会自己发表一个答案,但如果有人有现成的代码,他们欢迎救我一些努力:)
调用CreateFileMapping
时,将INVALID_HANDLE_VALUE
作为文件句柄传递:
如果hFile是INVALID_HANDLE_VALUE,则调用进程还必须在dwMaximumSizeHigh和dwMaximumSizeLow参数中指定文件映射对象的大小。 在这种情况下,CreateFileMapping将创建由系统分页文件而不是文件系统中的文件支持的指定大小的文件映射对象。
您可以使用匿名文件映射对象(将可继承的句柄传递给子进程),也可以使用命名文件映射。
我刚刚发现了一篇很好的MSDN文章 ,里面包含了下面粘贴的示例代码。
#include <windows.h> #include <stdio.h> #include <conio.h> #include <tchar.h> #define BUF_SIZE 256 TCHAR szName[]=TEXT("Global\\MyFileMappingObject"); TCHAR szMsg[]=TEXT("Message from first process."); int _tmain() { HANDLE hMapFile; LPCTSTR pBuf; hMapFile = CreateFileMapping( INVALID_HANDLE_VALUE, // use paging file NULL, // default security PAGE_READWRITE, // read/write access 0, // maximum object size (high-order DWORD) BUF_SIZE, // maximum object size (low-order DWORD) szName); // name of mapping object if (hMapFile == NULL) { _tprintf(TEXT("Could not create file mapping object (%d).\n"), GetLastError()); return 1; } pBuf = (LPTSTR) MapViewOfFile(hMapFile, // handle to map object FILE_MAP_ALL_ACCESS, // read/write permission 0, 0, BUF_SIZE); if (pBuf == NULL) { _tprintf(TEXT("Could not map view of file (%d).\n"), GetLastError()); CloseHandle(hMapFile); return 1; } CopyMemory((PVOID)pBuf, szMsg, (_tcslen(szMsg) * sizeof(TCHAR))); _getch(); UnmapViewOfFile(pBuf); CloseHandle(hMapFile); return 0; }
#include <windows.h> #include <stdio.h> #include <conio.h> #include <tchar.h> #pragma comment(lib, "user32.lib") #define BUF_SIZE 256 TCHAR szName[]=TEXT("Global\\MyFileMappingObject"); int _tmain() { HANDLE hMapFile; LPCTSTR pBuf; hMapFile = OpenFileMapping( FILE_MAP_ALL_ACCESS, // read/write access FALSE, // do not inherit the name szName); // name of mapping object if (hMapFile == NULL) { _tprintf(TEXT("Could not open file mapping object (%d).\n"), GetLastError()); return 1; } pBuf = (LPTSTR) MapViewOfFile(hMapFile, // handle to map object FILE_MAP_ALL_ACCESS, // read/write permission 0, 0, BUF_SIZE); if (pBuf == NULL) { _tprintf(TEXT("Could not map view of file (%d).\n"), GetLastError()); CloseHandle(hMapFile); return 1; } MessageBox(NULL, pBuf, TEXT("Process2"), MB_OK); UnmapViewOfFile(pBuf); CloseHandle(hMapFile); return 0; }
您可以使用匿名文件映射(David Heffernan的答案在此步骤中更详细地介绍)处理继承/处理重复。 例如,在命令行上从父进程传递HANDLE,然后在子进程中使用DuplicateHandle
在子进程中获得一个有效的HANDLE。
CreateFileMapping文档说
多个进程可以通过使用单个共享文件映射对象或创建由相同文件支持的单独文件映射对象来共享相同文件的视图。 单个文件映射对象可以由多个进程通过在进程创建时继承句柄,复制句柄或者通过名称打开文件映射对象来共享。 有关更多信息,请参阅CreateProcess,DuplicateHandle和OpenFileMapping函数。
但是使用ramdisk可能更容易些。