Benefits

Accessing memory mapped files is faster than using direct read and write operations for two reasons.

  • Firstly, a system call is orders of magnitude slower than a simple change to a program’s local memory.
  • Secondly, in most operating systems the memory region mapped actually is the kernel’s page cache (file cache), meaning that no copies need to be created in user space.

Concepts

It implements demand Paging, meaning that file contents are not immediately read from disk and initially use no physical RAM at all. Instead, the actual reads from disk are performed after a specific location is accessed, in a lazy manner.

API

void *mmap(void *addr, size_t len, int prot,
           int flags, int fildes, off_t off);
ParameterDescription
addrThis is the address we want the file mapped into. The best way to use this is to set it to NULL and let the OS choose it for you. If you tell it to use an address the OS doesn’t like (for instance, if it’s not a multiple of the virtual memory page size), it’ll give you an error.
lenThis parameter is the length of the data we want to map into memory. This can be any length you want. (Aside: if len not a multiple of the virtual memory page size, you will get a blocksize that is rounded up to that size. The extra bytes will be 0, and any changes you make to them will not modify the file.)
protThe “protection” argument allows you to specify what kind of access this process has to the memory mapped region. This can be a bitwise-ORd mixture of the following values: PROT_READPROT_WRITE, and PROT_EXEC, for read, write, and execute permissions, respectively. The value specified here must be equivalent to or a subset of the modes specified in the open() system call that is used to get the file descriptor.
flagsThese are just miscellaneous flags that can be set for the system call. You’ll want to set it to MAP_SHARED if you’re planning to share your changes to the file with other processes, or MAP_PRIVATE otherwise. If you set it to the latter, your process will get a copy of the mapped region, so any changes you make to it will not be reflected in the original file—thus, other processes will not be able to see them. We won’t talk about MAP_PRIVATE here at all, since it doesn’t have much to do with IPC.
fildesThis is where you put that file descriptor you opened earlier.
offThis is the offset in the file that you want to start mapping from. A restriction: this must be a multiple of the virtual memory page size. This page size can be obtained with a call to getpagesize(). Note that 32-bit systems may support files with sizes that cannot be expressed by 32-bit unsigned integers, so this type is often a 64-bit type on such systems.
int fd, pagesize;
char *data;
 
fd = open("foo", O_RDONLY);
pagesize = getpagesize();
data = mmap((void*)0, pagesize, PROT_READ, MAP_SHARED, fd, pagesize);