Linux System V IPC Shared Memory Explained

This article explores how the Linux operating system handles inter-process communication (IPC) via System V shared memory. It covers the core architecture of memory mapping across process address spaces, the fundamental system call lifecycle, the Linux kernel's internal implementation using virtual file systems, synchronization necessities, and kernel resource tuning.

Understanding System V Shared Memory Architecture

Shared memory is the fastest form of Inter-Process Communication (IPC) available in Linux. Unlike message queues or pipes, which require data to be copied between user-space buffers and kernel space, shared memory maps a common region of physical RAM directly into the virtual address spaces of two or more independent processes. Once the mapping is established, processes read and write to this region just as they would with private memory, eliminating redundant kernel context switches and buffer copies.

The System V Shared Memory Lifecycle

Linux manages System V shared memory through four primary system calls, which govern the creation, attachment, detachment, and destruction of segments.

1. Key Generation: ftok

Processes locate the same shared memory segment using an IPC key of type key_t. The ftok() utility function hashes a file path and a project identifier to generate a reproducible key:

key_t key = ftok("/path/to/valid/file", 'R');

2. Allocation: shmget

The shmget() (shared memory get) system call allocates a new shared memory segment or retrieves an existing one associated with the key:

int shmid = shmget(key, size, IPC_CREAT | 0666);

If IPC_CREAT is specified, the Linux kernel sets up an internal descriptor (struct shmid_kernel) and assigns a unique non-negative integer identifier known as the shmid.

3. Attachment: shmat

Calling shmget() does not make the memory accessible to the calling process. The process must attach the segment to its own address space using shmat():

void *addr = shmat(shmid, NULL, 0);

Passing NULL allows the Linux kernel to choose an unmapped page-aligned address in the process’s virtual memory space. The kernel updates the process's page table entries to point to the physical memory frames backing the shared segment.

4. Detachment: shmdt

When a process finishes using the segment, it detaches it with shmdt():

shmdt(addr);

Detaching removes the segment from the process's page tables, but the memory segment and its contents persist in the kernel.

5. Control and Removal: shmctl

Segments persist until explicitly destroyed or until the system reboots. To delete a segment, shmctl() must be invoked with the IPC_RMID command:

shmctl(shmid, IPC_RMID, NULL);

This marks the segment as destroyed. The kernel frees the physical pages as soon as the last attached process calls shmdt() or exits.

Kernel Implementation Mechanics

Under the hood, Linux treats System V shared memory segments as pseudo-files residing in an internal instance of tmpfs (often referred to as shmfs).

  1. Page Table Manipulation: When shmat() is called, the kernel creates a vm_area_struct in the process's memory map (mm_struct). This virtual memory area is backed by pages allocated from the page cache of the internal tmpfs file.
  2. Copy-on-Demand (Demand Paging): Physical memory pages are typically not allocated immediately during shmget(). Instead, physical frames are assigned on demand when a process triggers a page fault by reading from or writing to the mapped virtual address.
  3. Reference Counting: The kernel maintains a counter of active attachments (shm_nattch). When a process terminates, the kernel automatically detaches any attached shared segments, decrementing this count.

Synchronization Requirements

Because the kernel does not mediate read and write operations inside an attached segment, System V shared memory does not provide implicit synchronization or mutual exclusion. Simultaneous writes by multiple processes can cause race conditions and data corruption.

To maintain consistency, developers must pair shared memory with synchronization primitives:

Monitoring and Kernel Tunables

Linux provides both command-line tools and kernel interfaces to inspect and configure System V IPC parameters.

System Utilities

Kernel Limits

System limits can be inspected and adjusted via /proc/sys/kernel/: