Memory-Mapped files

When more than two threads are running in same process, or when a process starts more than two threads. Both threads are running in the process space of the same process, this means that both the threads can share the same information. For example parent process declares a variable ‘V1’ and creates two threads T1 and T2, then both T1 and T2 can access V1 and change it’s value. But when two threads belong to two different process they can not share any information. For this purpose we used pipes and sockets earlier and there are some more techniques through which we can make two threads communicate. Among all the techniques Memory-Mapped files are the most preferred one.

Conceptually memory-mapped file is a disk-based file that is loaded into the primary memory. The OS can read and write into this file in a way which is very similar to reading and writing from an ordinary file ( like the once you have been using to read and write information for your programming assignments, a txt file for example).

There is one big difference however in memory-mapped file and ordinary file. Unlike ordinary file a memory-mapped file can be accessed by two process at the same time, this is done by mapping the file into their address spaces. There is one small problem here, memory-mapped file are not protected against critical section problem. You have to use the regular locking mechanism, mutex and semaphore ex., for managing the critical section yourself.

Three steps to use memory-mapped files :

  • Obtain a handle to the file by creating or opening it ( equivalent to statement ifstream in(“in.txt”) when you would open an ordinary file in C++ )
  • Reserve virtual address space for the file.
  • Establish a mapping between the file and your virtual address space.

A file handle is obtained using CreateFile or OpenFile. The CreateFile function is discussed in Lab-5. when it is used with memory-mapped files, the normal parameters are used to create/open the file.

After a file has been opened, a file-mapping object stores the mapping information. It is created with CreaFileMapping, as follows.

HANDLE CreateFileMapping(

HANDLE hfile,

LPSECURITY_ATTRIBUTE

lpFileMappingAttributes,

DWORD flProtect,

DWORD dwMaximumSizeHigh,

DWORD dwMaximumSizeLow,

LPCSTR lpName );

The mapping object may use a name, lpName, or use NULL. If lpName is NULL, the mapping object is created without a name and cannot normally be shared. If lpName is defined and already exists, this request is to use the existing named mapping object. If lpName is defined but does not exit, it is created.

Once the mapping object has been created, the address space will have been established, though the file contents will not have actually been mapped to the process’s address space. This is accomplished using the following.

LPVOID MapViewOfFile(

HANDLE hFileMappingObject,

DWORD dwDesiredAccess,

DWORD dwfileoffsetHigh,

DWORD dwfileoffsetLow,

DWORD dwNumberOfBytesToMap

);