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.

🔑 Key line

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 offsets
struct SharedData {
pthread_mutex_t mutex; // sync in shared mem
int value;
char message[256];
};
// Writer process
int 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 use
pthread_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 it

What this lesson walks through

  1. 01shm_open + mmap — both processes see the same page
  2. 02Writer (A) writes value=42 — no sync yet
  3. 03RACE: A and B write simultaneously without sync
  4. 04pthread_mutex with PTHREAD_PROCESS_SHARED
  5. 05Reader (B) acquires lock — sees consistent state
  6. 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.

← Previous
IPC: Pipes & FIFOs — Unidirectional Byte Streams Between Processes
Next →
IPC: POSIX Message Queues — Priority-Ordered Framed Messages