Lesson 10advancedIPC

Shared Memory

System V shared memory for the fastest IPC. Covers shmget/shmat/shmdt/shmctl, sharing structs and arrays between processes, and a multi-program scoreboard architecture with separate creator, updater, and viewer processes.

shmgetshmatshared-memoryIPCshmctl
1

Shared Memory Creator

Creating a shared memory segment with shmget, attaching it with shmat, and writing initial data.

02-basic-example/creator.c131 lines
2

Shared Memory Consumer

Attaching to an existing shared memory segment and reading data written by the creator.

02-basic-example/consumer.c93 lines
3

Position Creator

Creating a shared memory segment containing a Position struct with x/y coordinates.

03-positions/position_creator.c87 lines
4

Position Updater

A process that continuously updates the position coordinates in shared memory.

03-positions/position_updater.c79 lines
/*
 * position_updater.c — Position struct updater — modifies shared memory
 *
 * Key concepts: Attaching to existing shared memory, updating struct fields
 * Compile: gcc -o pos_update position_updater.c
 * Run:     ./prog
 */
// position_updater.c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h> 
#include <sys/shm.h>
#include <sys/ipc.h>
#include <signal.h>


#define SHM_KEY 0x1234 // Must match creator's key
#define SHM_SIZE sizeof(Position)

typedef struct
{
    float x;
    float y;
} Position;


int shmid;
Position *pos;

// Signal handler to detach shared memory upon termination
void handle_sigint(int sig) {
    if(shmdt(pos) == -1) {
        perror("shmdt failed");
    }
    printf("\nPosition updater detached and exiting.\n");
    exit(0);
}

int main() {
    printf("\n");
    printf("══════════════════════════════════════\n");
    printf("  Position struct updater — modifies\n");
    printf("══════════════════════════════════════\n\n");
    // Register signal handler
    signal(SIGINT, handle_sigint);

    // Access shared memory
    shmid = shmget(SHM_KEY, SHM_SIZE, 0666);
    if(shmid < 0) {
        perror("shmget failed");
        exit(EXIT_FAILURE);
    }

    // Attach to shared memory
    pos = (Position *) shmat(shmid, NULL, 0);
    if(pos == (Position *) -1) {
        perror("shmat failed");
        exit(EXIT_FAILURE);
    }

    printf("Position updater started. Updating position every second.\n");

    // Update position in a loop
    while(1) {
        // Simple movement logic: move diagonally
        pos->x += 1.0;
        pos->y += 1.0;

        printf("Updated Position: x = %.2f, y = %.2f\n", pos->x, pos->y);

        sleep(1);
    }

    // Detach from shared memory (unreachable in this example)
    shmdt(pos);

    return 0;
}
5

Position Viewer

Reads and displays the current position from shared memory — see live updates from the updater.

03-positions/position_viewer.c67 lines
/*
 * position_viewer.c — Position struct viewer — reads shared memory
 *
 * Key concepts: Polling shared memory, real-time data viewing
 * Compile: gcc -o pos_view position_viewer.c
 * Run:     ./prog
 */
// position_viewer.c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h> 
#include <sys/shm.h>
#include <sys/ipc.h>
#include <signal.h>
#include "position.h"

#define SHM_KEY 0x1234 // Must match creator's key
#define SHM_SIZE sizeof(Position)

int shmid;
Position *pos;

// Signal handler to detach shared memory upon termination
void handle_sigint(int sig) {
    if(shmdt(pos) == -1) {
        perror("shmdt failed");
    }
    printf("\nPosition viewer detached and exiting.\n");
    exit(0);
}

int main() {
    printf("\n");
    printf("══════════════════════════════════════\n");
    printf("  Position struct viewer — reads sha\n");
    printf("══════════════════════════════════════\n\n");
    // Register signal handler
    signal(SIGINT, handle_sigint);

    // Access shared memory
    shmid = shmget(SHM_KEY, SHM_SIZE, 0666);
    if(shmid < 0) {
        perror("shmget failed");
        exit(EXIT_FAILURE);
    }

    // Attach to shared memory
    pos = (Position *) shmat(shmid, NULL, 0);
    if(pos == (Position *) -1) {
        perror("shmat failed");
        exit(EXIT_FAILURE);
    }

    printf("Position viewer started. Reading position every second.\n");

    // Read position in a loop
    while(1) {
        printf("Current Position: x = %.2f, y = %.2f\n", pos->x, pos->y);
        sleep(1);
    }

    // Detach from shared memory (unreachable in this example)
    shmdt(pos);

    return 0;
}
6

Shared Array Creator

Allocating shared memory large enough for an integer array and initializing it.

04-array/creator.c75 lines
/*
 * creator.c — Shared array creator — allocates shared memory for array
 *
 * Key concepts: shmget with array size, shared memory initialization
 * Compile: gcc -o arr_create creator.c
 * Run:     ./prog
 */
// array_creator.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/shm.h>
#include <sys/ipc.h>

const char* SHM_KEY =  '0x2345'; // Unique key for shared memory
const int ARRAY_SIZE =  10 ; // Size of the integer array

int shmid;
int *shared_array;

void handle_sigint(int sig)
{
    printf("\nCaught signal %d, detaching and removing shared memory.\n", sig);
    shmdt(shared_array);
    shmctl(shmid, IPC_RMID, NULL);
    exit(EXIT_SUCCESS);
}

int main()
{
    printf("\n");
    printf("══════════════════════════════════════\n");
    printf("  Shared array creator — allocates s\n");
    printf("══════════════════════════════════════\n\n");

    signal(SIGINT, handle_sigint);
    // Create shared memory segment
    shmid = shmget(SHM_KEY, sizeof(int) * ARRAY_SIZE, IPC_CREAT | 0666);
    if (shmid < 0)
    {
        perror("shmget failed");
        exit(EXIT_FAILURE);
    }

    // Attach to shared memory
    shared_array = (int *)shmat(shmid, NULL, 0);
    if (shared_array == (int *)-1)
    {
        perror("shmat failed");
        // Remove shared memory segment
        shmctl(shmid, IPC_RMID, NULL);
        exit(EXIT_FAILURE);
    }

    // Initialize array to zero
    for (int i = 0; i < ARRAY_SIZE; i++)
    {
        shared_array[i] = 0;
    }

    printf("[Creator PID %d] Shared memory", getpid() for integer array created and initialized.\n");
    printf("Press Ctrl+C to terminate the creator.\n");

    // Keep the creator running to maintain the shared memory
    while (1)
    {
        sleep(1);
    }

  

    return 0;
}
7

Shared Array Producer

Writing values into a shared array that other processes can read.

04-array/producer.c71 lines
/*
 * producer.c — Shared array producer — writes values to shared array
 *
 * Key concepts: Writing to shared memory array, synchronization concerns
 * Compile: gcc -o arr_prod producer.c
 * Run:     ./prog
 */
// array_producer.c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h> 
#include <sys/shm.h>
#include <sys/ipc.h>
#include <signal.h>

const char* SHM_KEY =  '0x2345'; // Unique key for shared memory
const int ARRAY_SIZE =  10 ; // Size of the integer array

int shmid;
int *shared_array;
int current_index = 0;

// Signal handler to detach shared memory upon termination
void handle_sigint(int sig) {
    if(shmdt(shared_array) == -1) {
        perror("shmdt failed");
    }
    printf("\nArray producer detached and exiting.\n");
    exit(0);
}

int main() {
    printf("\n");
    printf("══════════════════════════════════════\n");
    printf("  Shared array producer — writes val\n");
    printf("══════════════════════════════════════\n\n");
    // Register signal handler
    signal(SIGINT, handle_sigint);

    // Access shared memory
    shmid = shmget(SHM_KEY, sizeof(int) * ARRAY_SIZE, 0666);
    if(shmid < 0) {
        perror("shmget failed");
        exit(EXIT_FAILURE);
    }

    // Attach to shared memory
    shared_array = (int *) shmat(shmid, NULL, 0);
    if(shared_array == (int *) -1) {
        perror("shmat failed");
        exit(EXIT_FAILURE);
    }

    printf("Array producer started. Populating array every second.\n");

    // Populate array in a loop
    while(1) {
        shared_array[current_index] = current_index + 1;
        printf("Producer: Set shared_array[%d] = %d\n", current_index, shared_array[current_index]);

        current_index = (current_index + 1) % ARRAY_SIZE;

        sleep(1);
    }

    // Detach from shared memory (unreachable in this example)
    shmdt(shared_array);

    return 0;
}
8

Shared Array Consumer

Reading values from the shared array populated by the producer process.

04-array/consumer.c70 lines
/*
 * consumer.c — Shared array consumer — reads from shared array
 *
 * Key concepts: Reading shared memory array
 * Compile: gcc -o arr_cons consumer.c
 * Run:     ./prog
 */
// array_consumer.c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h> 
#include <sys/shm.h>
#include <sys/ipc.h>
#include <signal.h>

const char* SHM_KEY =  '0x2345'; // Unique key for shared memory
const int ARRAY_SIZE =  10 ; // Size of the integer array

int shmid;
int *shared_array;

// Signal handler to detach shared memory upon termination
void handle_sigint(int sig) {
    if(shmdt(shared_array) == -1) {
        perror("shmdt failed");
    }
    printf("\nArray consumer detached and exiting.\n");
    exit(0);
}

int main() {
    printf("\n");
    printf("══════════════════════════════════════\n");
    printf("  Shared array consumer — reads from\n");
    printf("══════════════════════════════════════\n\n");
    // Register signal handler
    signal(SIGINT, handle_sigint);

    // Access shared memory
    shmid = shmget(SHM_KEY, sizeof(int) * ARRAY_SIZE, 0666);
    if(shmid < 0) {
        perror("shmget failed");
        exit(EXIT_FAILURE);
    }

    // Attach to shared memory
    shared_array = (int *) shmat(shmid, NULL, 0);
    if(shared_array == (int *) -1) {
        perror("shmat failed");
        exit(EXIT_FAILURE);
    }

    printf("Array consumer started. Reading array every second.\n");

    // Read array in a loop
    while(1) {
        printf("Current Array State:\n");
        for(int i = 0; i < ARRAY_SIZE; i++) {
            printf("shared_array[%d] = %d\n", i, shared_array[i]);
        }
        printf("-------------------------\n");
        sleep(1);
    }

    // Detach from shared memory (unreachable in this example)
    shmdt(shared_array);

    return 0;
}
9

Scoreboard Creator

Creating shared memory for a Scoreboard struct defined in a shared header file.

05-scoreboard-struct/scoreboard_creator.c59 lines
/*
 * scoreboard_creator.c — Scoreboard creator — shared struct with header file
 *
 * Key concepts: shmget, shared header file for struct definition
 * Compile: gcc -o sb_create scoreboard_creator.c
 * Run:     ./prog
 */
// scoreboard_creator.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h> 
#include <sys/shm.h>
#include <sys/ipc.h>
#include "scoreboard.h"

#define SHM_KEY 0x1234 // Unique key for shared memory

int main() {
    printf("\n");
    printf("══════════════════════════════════════\n");
    printf("  Scoreboard creator — shared struct\n");
    printf("══════════════════════════════════════\n\n");
    int shmid;
    Scoreboard *scoreboard;

    // Create shared memory segment
    shmid = shmget(SHM_KEY, sizeof(Scoreboard), IPC_CREAT | 0666);
    if (shmid < 0) {
        perror("shmget");
        exit(EXIT_FAILURE);
    }

    // Attach to shared memory
    scoreboard = (Scoreboard *) shmat(shmid, NULL, 0);
    if (scoreboard == (Scoreboard *) -1) {
        perror("shmat");
        exit(EXIT_FAILURE);
    }

    // Initialize scoreboard
    scoreboard->total_players = 0;
    for(int i = 0; i < MAX_PLAYERS; i++) {
        scoreboard->players[i].player_id = -1; // -1 indicates empty slot
        strcpy(scoreboard->players[i].player_name, "Empty");
        scoreboard->players[i].score = 0;
    }

    printf("Scoreboard initialized in shared memory.\n");

    // Detach from shared memory
    if (shmdt(scoreboard) == -1) {
        perror("shmdt");
        exit(EXIT_FAILURE);
    }

    return 0;
}
10

Scoreboard Updater

Updating scores in the shared scoreboard — demonstrates multi-program struct sharing.

05-scoreboard-struct/scoreboard_updater.c100 lines
11

Scoreboard Viewer

Displaying the current scoreboard by reading from shared memory.

05-scoreboard-struct/scoreboard_viewer.c68 lines
/*
 * scoreboard_viewer.c — Scoreboard viewer — displays live scores from shared memory
 *
 * Key concepts: Reading shared struct, polling for changes
 * Compile: gcc -o sb_view scoreboard_viewer.c
 * Run:     ./prog
 */
// scoreboard_viewer.c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h> 
#include <sys/shm.h>
#include <sys/ipc.h>
#include "scoreboard.h"

#define SHM_KEY 0x1234 // Must match creator's key

int main() {
    printf("\n");
    printf("══════════════════════════════════════\n");
    printf("  Scoreboard viewer — displays live \n");
    printf("══════════════════════════════════════\n\n");
    int shmid;
    Scoreboard *scoreboard;

    // Access shared memory
    shmid = shmget(SHM_KEY, sizeof(Scoreboard), 0666);
    if (shmid < 0) {
        perror("shmget");
        exit(EXIT_FAILURE);
    }

    scoreboard = (Scoreboard *) shmat(shmid, NULL, 0);
    if (scoreboard == (Scoreboard *) -1) {
        perror("shmat");
        exit(EXIT_FAILURE);
    }

    printf("Viewing Scoreboard:\n");

    while(1) {
        system("clear"); // Clear the terminal for better readability

        printf("=== Game Scoreboard ===\n");
        printf("Total Players: %d\n\n", scoreboard->total_players);
        printf("%-5s %-20s %-10s\n", "ID", "Player Name", "Score");
        printf("----------------------------------------\n");

        for(int i = 0; i < MAX_PLAYERS; i++) {
            if(scoreboard->players[i].player_id != -1) {
                printf("%-5d %-20s %-10d\n",
                       scoreboard->players[i].player_id,
                       scoreboard->players[i].player_name,
                       scoreboard->players[i].score);
            }
        }

        printf("\nPress Ctrl+C to exit.\n");

        sleep(3); // Refresh every 3 seconds
    }

    // Detach (unreachable code due to infinite loop)
    shmdt(scoreboard);

    return 0;
}

Open Full Terminal

Get a Linux terminal with all 11 files from this lesson pre-loaded. Compile, run, and experiment freely.