mmap in one paragraph
mmap maps a file or anonymous memory into the process address space. Reads/writes go through the page cache (file-backed) or anonymous pages — no separate read/write buffer copy for sequential access. munmap tears down the mapping.
Key flags
| Flag | Semantics |
|---|---|
MAP_PRIVATE | Copy-on-write — changes don't hit disk; default for file read |
MAP_SHARED | Writes visible to other mappers and eventually persisted (with msync) |
MAP_ANONYMOUS | No file backing — heap alternative, zero-filled on first touch |
PROT_READ/WRITE/EXEC | Page permission bits checked by MMU |
mmap vs read/write
- mmap wins for random access to large files, repeated access, shared mappings.
- read/write wins for small one-shot reads, streaming with explicit buffer control.
- Databases (LMDB, SQLite in some modes) mmap data files for OS-managed paging.
Shared memory IPC
mmap(MAP_SHARED) on shm_open or /dev/shm lets processes share a byte array without serializing through sockets. POSIX shared memory + semaphores or futexes for synchronization. Faster than pipe/socket for bulk data — but you own cache coherency and lifetime.
fork + CoW
After fork, parent and child share physical pages marked read-only. First write triggers a copy-on-write fault — kernel duplicates the page. This is why fork is fast but memory usage grows with divergent writes.
Senior-level signal
MAP_SHARED writes to a file aren't durable until msync(MS_SYNC) or fsync on the fd — crash mid-write and you've corrupted the mapping, not just the buffer. Production databases pair mmap with explicit sync points or bypass mmap for the WAL.
Where this goes next
File Systems, Inodes & the VFS explains how those mmap'd file paths resolve through directories and inode metadata to blocks on disk.
Further Reading
Hands-On Tasks (Optional)
Low-setup exercises on your local machine. No autograding — the goal is to build intuition, not pass a test.
- mmap a file read-only15m
Python one-liner: `import mmap, os; f=open('/etc/hosts'); m=mmap.mmap(f.fileno(), 0, access=mmap.ACCESS_READ); print(m[:100])`. Or use `cat /proc/self/maps` after running to see the file mapping.