System V Shared Memory inux IPC Series

 

System V Shared Memory
Chapter 48 – TLPI | Linux IPC Series | EmbeddedPathashala
Part 1
Introduction & Overview
IPC
Inter-Process Communication
Fast
Zero-Copy Data Sharing

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.

Key Terms You Will Learn

shmget() shmat() shmdt() shmctl() key_t IPC_CREAT IPC_RMID IPC_PRIVATE shmid_ds shm_nattch ftok() SHM_RDONLY

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.

Process A
Stack
Heap
Shared Region
addr: 0x7f000000
Code (.text)

Page Table A
Physical RAM
Shared Segment
e.g. 4096 bytes
Page Table B

Process B
Stack
Shared Region
addr: 0x7e000000
Heap
Code (.text)
Virtual addresses differ per process, but both map to the same physical RAM page. A write by Process A is instantly visible in Process B.

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

1. shmget() — Create or locate segment
2. shmat() — Attach into address space
3. Read / Write data (no syscalls)
4. shmdt() — Detach from address space
5. shmctl(IPC_RMID) — Delete segment

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

Q1. Why is shared memory the fastest IPC mechanism?

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.

Q2. What is the difference between detaching and deleting a shared memory segment?

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).

Q3. What happens to shared memory segments when a process calls exec()?

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.

Q4. Does shared memory need synchronization? Why?

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.

Q5. Why should you never store raw pointers inside a shared memory segment?

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.

Q6. What is kernel persistence in the context of shared memory?

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.

Chapter 48 – System V Shared Memory Series

EmbeddedPathashala.com | Free Embedded & Linux Tutorials

Leave a Reply

Your email address will not be published. Required fields are marked *