ipc · advanced
IPC: Shared Memory — Zero-Copy Direct Memory Access Between Processes
POSIX shared memory (shm_open + mmap) maps the same physical RAM page into multiple process virtual address spaces. shm_open('/name') creates or opens a shared object; ftruncate() sets its size; mmap(MAP_SHARED) maps it into virtual memory — different virtual addresses for each process, same physical page. Writes are immediately visible: no copy, no system call per access — fastest IPC mechanism. The downside: no synchronization built-in. Data races are immediate UB. Fix: put a pthread_mutex_t initialized with PTHREAD_PROCESS_SHARED inside the shared struct. munmap() removes the mapping from one process; shm_unlink() removes the filesystem name. Memory persists until all mappings are released. System V shmget is the older API: ftok+shmget+shmat+shmdt+shmctl(IPC_RMID). Use shared memory for high-throughput data (market feeds, video frames, game state). For structured messages use POSIX message queues; for streams use pipes.
mmap(MAP_SHARED) maps the same physical page into two virtual address spaces — zero copy IPC; fastest mechanism but requires explicit sync (PTHREAD_PROCESS_SHARED mutex or semaphore inside the shared region); shm_unlink removes the name; memory persists until all processes munmap.
The code
// POSIX shared memory — fastest IPC (zero copy)// Shared data structure — must be POD or use offsetsstruct SharedData { pthread_mutex_t mutex; // sync in shared mem int value; char message[256];};
// Writer processint fd = shm_open("/myapp_shm", O_CREAT | O_RDWR, 0644);ftruncate(fd, sizeof(SharedData));void* ptr = mmap(nullptr, sizeof(SharedData), PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);close(fd); // fd no longer needed after mmap
auto* shd = static_cast<SharedData*>(ptr);
// Mutex must be initialized for shared memory usepthread_mutexattr_t attr;pthread_mutexattr_init(&attr);pthread_mutexattr_setpshared(&attr, PTHREAD_PROCESS_SHARED);pthread_mutex_init(&shd->mutex, &attr);
pthread_mutex_lock(&shd->mutex);shd->value = 42;strcpy(shd->message, "hello from A");pthread_mutex_unlock(&shd->mutex);
munmap(ptr, sizeof(SharedData));
// Reader process (separate binary/PID)int fd = shm_open("/myapp_shm", O_RDWR, 0);void* ptr = mmap(nullptr, sizeof(SharedData), PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);auto* shd = static_cast<SharedData*>(ptr);pthread_mutex_lock(&shd->mutex);printf("value=%d msg=%s\n", shd->value, shd->message);pthread_mutex_unlock(&shd->mutex);munmap(ptr, sizeof(SharedData));shm_unlink("/myapp_shm"); // last user removes itWhat this lesson walks through
- 01shm_open + mmap — both processes see the same page
- 02Writer (A) writes value=42 — no sync yet
- 03RACE: A and B write simultaneously without sync
- 04pthread_mutex with PTHREAD_PROCESS_SHARED
- 05Reader (B) acquires lock — sees consistent state
- 06POSIX vs System V — API comparison and when to use shm
shm_open('/myapp_shm') creates or opens a shared memory object. ftruncate() sets its size. mmap() maps it into the process virtual address space. The key: the MMU maps different virtual addresses in Process A and Process B to the SAME physical page — zero copy; writes are immediately visible to the other process.
See it animated — step by step, at your own pace
Unlock the full interactive walkthrough of IPC: Shared Memory — Zero-Copy Direct Memory Access Between Processes and 100+ animated C++ interview lessons.