System V Shared Memory is the fastest form of IPC on Linux. Instead of copying data through pipes or message queues, two or more processes share the exact same block of physical RAM. One process writes — all others see it instantly. No kernel involvement per read or write operation.
The API has four main system calls: shmget() to create or open a segment, shmat() to attach it into a process’s address space, shmdt() to detach it, and shmctl() to control or delete it.
What is Shared Memory?
Every process has its own private memory. Process A cannot see Process B’s variables. The kernel enforces this separation. Shared memory is a deliberate exception — the kernel maps the same physical RAM page(s) into two or more processes at the same time.
addr: 0x7f000000
e.g. 4096 bytes
addr: 0x7e000000
Notice the virtual addresses are different (0x7f000000 vs 0x7e000000). This is normal and important — you must never store raw pointers inside the shared segment, because a pointer computed in Process A will point to the wrong location in Process B. Store offsets or use structs with values only.
Why is it the Fastest IPC?
| IPC Method | Data Copies | Kernel Call Per I/O? | Speed |
|---|---|---|---|
| Pipe / FIFO | 2 (user→kernel + kernel→user) | Yes | Slow |
| Message Queue | 2 | Yes | Moderate |
| Socket | 2+ | Yes | Moderate |
| Shared Memory | 0 | No (only setup/teardown) | Fastest |
After shmat(), reading and writing shared memory is no different from accessing a local array. No system calls, no copying. The kernel is completely out of the critical path.
The catch: Shared memory provides zero synchronization. If two processes write at the same time, data gets corrupted. You must always pair shared memory with a synchronization mechanism — typically System V semaphores.
Shared Memory Lifecycle
Step 5 marks the segment for deletion. Actual removal happens when the last attached process detaches.
Minimal Usage Skeleton
Here is the complete skeleton showing all four API calls together:
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <stdio.h>
#include <string.h>
int main(void)
{
int shmid;
void *addr;
/* Step 1: Create a 4096-byte shared memory segment */
shmid = shmget(IPC_PRIVATE, 4096, IPC_CREAT | 0600);
if (shmid == -1) {
perror("shmget");
return 1;
}
/* Step 2: Attach – kernel maps it into our address space */
addr = shmat(shmid, NULL, 0);
if (addr == (void *)-1) {
perror("shmat");
return 1;
}
/* Step 3: Use it like any normal memory */
strcpy((char *)addr, "Hello from shared memory!");
printf("Read back: %s\n", (char *)addr);
/* Step 4: Detach – remove from our address space */
if (shmdt(addr) == -1) {
perror("shmdt");
return 1;
}
/* Step 5: Delete the segment from the kernel */
if (shmctl(shmid, IPC_RMID, NULL) == -1) {
perror("shmctl");
return 1;
}
return 0;
}
/* Compile: gcc -o skeleton skeleton.c */
Key Properties to Remember
| Property | Behaviour |
|---|---|
| fork() | Child inherits all attached segments. Both parent and child share the same memory. |
| exec() | All attached segments are automatically detached. The new program starts clean. |
| Process exit | All attached segments are automatically detached on termination. |
| Persistence | Segment survives process exit until explicitly deleted with IPC_RMID (kernel-persistent). |
| Synchronization | Not provided. Must be added manually using semaphores or mutexes. |
| Size rounding | Kernel rounds size up to nearest page size (usually 4096 bytes). |
Interview Questions
Because there is no data copying involved. Pipes and message queues require two copies per message (user→kernel on write, kernel→user on read). Shared memory maps the same physical RAM into both processes. After setup, reading and writing shared memory is exactly like accessing a local array — no system calls, no copying, just RAM speed.
Detaching (shmdt()) removes the mapping from the calling process’s virtual address space only. The segment still exists in the kernel and other attached processes can still use it. Deleting (shmctl(IPC_RMID)) marks the segment for removal. The kernel actually frees the RAM only when every process has detached (attach count hits zero).
All attached shared memory segments are automatically detached. The new program loaded by exec() gets a fresh address space with no inherited attachments. The segment itself still exists in the kernel — it is not deleted — but the new program must call shmat() again if it wants to use it.
Yes, always. Shared memory provides no built-in locking. If Process A writes while Process B reads simultaneously, you get a data race and undefined behavior. You must use an external mechanism — System V semaphores, POSIX semaphores, or a pthread_mutex_t with PTHREAD_PROCESS_SHARED — to coordinate access.
Because each process attaches the segment at a different virtual address. A pointer computed in Process A (e.g. 0x7f004000) points to completely different data in Process B’s address space. The correct approach is to store offsets from the start of the segment, which are consistent across all processes.
System V shared memory segments persist in the kernel even after all processes that created or used them have exited. The segment keeps existing — consuming RAM — until someone explicitly calls shmctl(IPC_RMID) or the system reboots. This is unlike anonymous memory which is freed automatically on process exit. You can see leaked segments with ipcs -m.
EmbeddedPathashala.com | Free Embedded & Linux Tutorials
