Shared Memory
The fastest IPC — mapping the same memory into multiple processes with mmap and POSIX shared memory, and why it needs explicit synchronization.
Shared memory is the fastest form of IPC: instead of copying data through the kernel (as pipes do), two processes map the same physical pages into their address spaces and read and write them directly. The trade-off is that it provides no synchronization of its own — you must add that yourself.
Why it's fast
With pipes or sockets, every byte is copied from one process into the kernel and out to another. With shared memory, once the region is set up there is no copying and no kernel involvement on each access — both processes simply dereference pointers into the same RAM. That speed is why it's used in databases, high-performance computing, and multimedia.
mmap
mmap() maps something into your address space and returns a pointer. It has two main uses:
- File-backed — map a file so its contents appear as memory; writes go back to the file.
- Anonymous (
MAP_ANONYMOUS) — plain memory not backed by any file.
The visibility of writes depends on the flag:
MAP_SHARED— changes are visible to other processes mapping the same object.MAP_PRIVATE— copy-on-write; changes stay private to your process.
int fd = open("data.bin", O_RDWR);
char *p = mmap(NULL, len, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
p[0] = 'X'; // writes straight through to the file / shared region
munmap(p, len); // unmap when done (msync() forces a file flush)POSIX shared memory (recommended)
The modern, file-descriptor-based API. Create (or open) a named object, size it, then mmap
it — the object lives under /dev/shm/:
int fd = shm_open("/mydata", O_CREAT | O_RDWR, 0644);
ftruncate(fd, len); // set its size
void *p = mmap(NULL, len, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
// ... share via p ...
shm_unlink("/mydata"); // remove the objectBecause it uses file descriptors, it integrates cleanly with the rest of the POSIX API and is cleaned up when unlinked.
System V shared memory (legacy)
The older API is still common: shmget() (create/get by a key from ftok()), shmat() /
shmdt() (attach/detach), and shmctl(..., IPC_RMID) to remove. Segments persist until
removed or reboot — inspect them with ipcs -m and clean up with ipcrm. Prefer POSIX for
new code.
You must synchronize
Shared memory is just memory — nothing stops two processes writing the same bytes at once, so the synchronization rules apply across processes too:
Protect access with process-shared primitives — POSIX named semaphores (sem_open),
process-shared mutexes (a pthread_mutex_t with PTHREAD_PROCESS_SHARED placed in the
shared region), or file locks.
Practice / lab
mmapa file, modify it through the pointer, and confirm the change persists aftermunmap.- Write a POSIX writer/reader pair: one
shm_open+ftruncate+mmap+writes, the other reads; clean up withshm_unlink. - Put a counter in shared memory, increment it from several processes, watch it race, then fix it with a named semaphore.
- Compare throughput of shared memory vs. pipes vs. files.
Homework
- IPC-3: Shared Array — a
shared_arrayclass shared between processes, synchronized with a cross-process semaphore.
References & resources
Required
- Understanding
mmap(Baeldung) - POSIX shared memory with
shm_open(video) - The Linux Programming Interface (Kerrisk) — Ch. 49 (memory mappings), 54 (POSIX shm)
Optional / enrichment
Self-check
- Why is shared memory the fastest IPC mechanism?
- What is the difference between
MAP_SHAREDandMAP_PRIVATE? - Which calls create and size a POSIX shared-memory object, and where does it appear?
- How does System V shared memory differ from POSIX, and how do you inspect/remove it?
- Why does shared memory require explicit synchronization, and what can provide it?