Named file mapping provides an easy way to create a block of shared memory. One process creates a file mapping object, specifying a name that can be used by other processes to obtain a handle to the mapping object. Then each process uses the mapping object to map a view of the file into its own address space. The views of all processes for a single mapping object are mapped into the same sharable pages of physical storage. However, the virtual addresses of the mapped views can vary from one process to another. And although sharable, the pages of physical storage are not global since they are not visible in the address space of processes that have not mapped a view of the file.
CreateFileMapping creates a file mapping object, but does not map the file. The file to be mapped is specified by a handle to an open file as returned by CreateFile . If the handle is 0xFFFFFFFF, the system's paging file will be used. Mapping a named file in the file system is useful if you want to share the data in an existing file, or if you want use the file to save the data generated by the sharing processes. The paging file should be used if you are only interested in creating a block of shared memory. If you map a named file, you should open it for exclusive access and keep the handle open until you are finished with the shared memory. This will prevent other processes from opening another handle on the file to use ReadFile, WriteFile , or to create additional mapping objects for the same file, any of which could lead to unpredictable results.
CreateFileMapping allows you to associate a name with the file mapping object. This name can be used by other processes to open a handle to the same object using the OpenFileMapping call. The name could include any character except for NULL and the path name separator character “\”; and would be limited to MAX_PATH bytes (MAX_PATHW for Unicode). The file mapping object names exist in their own flat name space, so they will not collide with the names of other objects (files, events, semaphores, etc.). Note that the process of setting up shared memory using named file mapping requires synchronization to ensure that the creating process creates the mapping object before the other processes try to open it. If no object name is specified in the CreateFileMapping call, the handle can still be shared with other processes by the less convenient means of handle duplication or inheritance.
When a process uses MapViewOfFile to map a view of a file, it allocates shared, committed pages with read/write or read only access. The access specified in MapViewOfFile (FILE_MAP_READ or FILE_MAP_WRITE) must be compatible with the access specified in CreateFileMapping or OpenFileMapping, and in the case of named files, when the file was opened with CreateFile . If more than one process has write access to the shared memory, a mutex object should be used to prevent simultaneous writing. The maximum size specified in the CreateFileMapping call limits the size of the views that can be mapped. A process may map the entire file or a portion of it, and the view may start at the beginning of the file or at any 64KB aligned offset in the file. Any pages committed by mapping a view will be released when the last process with a view on the mapping object either terminates or unmaps its view by calling UnmapViewOfFile . At this time, the named file (if any) associated with the mapping object will be updated. Updating a named file can also be forced by calling FlushViewOfFile.
The following example shows how two processes would use named file mapping to create a block of shared memory. Note that when the system's paging file is mapped (by using 0xFFFFFFFF instead of a file handle), the CreateFileMapping call must explicitly specify the size in bytes of the mapping. For named files, the mapping size can default to the current size of the file, if both high order and low order size parameters are 0. Each process has read/write access to the memory.
/**************************************************************/
/* creating process creates the mapping object */
/**************************************************************/
char *mapview;
HANDLE hMapObj;
// create named mapping object, size 4KB
hMapObj = CreateFileMapping((HANDLE) 0xFFFFFFFF,
NULL, // not inherited
PAGE_READWRITE,
0, // buffer size, hi order
0x1000, // buffer size, lo order
"shared_mem_map_obj" // object name
);
assert(hMapObj);
// map view of 4KB shared buffer
mapview = (char *) MapViewOfFile(hMapObj,
FILE_MAP_READ | FILE_MAP_WRITE,
0, // view offset, hi order
0, // view offset, lo order
0 // view size = max file size
);
assert(mapview);
/**************************************************************/
/* other processes use name to open handle to mapping object */
/**************************************************************/
char *mapview;
HANDLE hMapObj;
// open named mapping object for read/write access
hMapObj = OpenFileMapping(FILE_MAP_WRITE, // read/write access
FALSE, // no handle inheritance
"shared_mem_map_obj"); // object name
assert(hMapObj);
// map view of 4KB shared buffer
mapview = (char *) MapViewOfFile(hMapObj,
FILE_MAP_READ | FILE_MAP_WRITE,
0, // view offset, hi order
0, // view offset, lo order
0 // view size = max file size
);
assert(mapview);