Skip to content

Instantly share code, notes, and snippets.

@0xBigBoss
Created January 31, 2025 04:22
Show Gist options
  • Save 0xBigBoss/4f390d54d9c16b4c9d27361f36dbd531 to your computer and use it in GitHub Desktop.
Save 0xBigBoss/4f390d54d9c16b4c9d27361f36dbd531 to your computer and use it in GitHub Desktop.

Revisions

  1. 0xBigBoss created this gist Jan 31, 2025.
    202 changes: 202 additions & 0 deletions shm.c
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,202 @@
    /*
    * Example 1: POSIX Shared Memory
    * This example shows how to create, write to, and read from a POSIX shared memory segment
    */

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <fcntl.h>
    #include <sys/mman.h>
    #include <unistd.h>

    #define SHM_NAME "/my_shm"
    #define SHM_SIZE 1024

    // Structure to be shared between processes
    typedef struct {
    int count;
    char message[256];
    } SharedData;

    // Writer process
    void posix_writer() {
    // Create and open shared memory segment
    int fd = shm_open(SHM_NAME, O_CREAT | O_RDWR, 0666);
    if (fd == -1) {
    perror("shm_open");
    exit(1);
    }

    // Set the size of the shared memory segment
    if (ftruncate(fd, SHM_SIZE) == -1) {
    perror("ftruncate");
    exit(1);
    }

    // Map shared memory to process address space
    SharedData* shared_data = (SharedData*)mmap(NULL, SHM_SIZE,
    PROT_READ | PROT_WRITE,
    MAP_SHARED, fd, 0);
    if (shared_data == MAP_FAILED) {
    perror("mmap");
    exit(1);
    }

    // Write to shared memory
    shared_data->count = 42;
    strcpy(shared_data->message, "Hello from POSIX shared memory!");

    // Cleanup
    munmap(shared_data, SHM_SIZE);
    close(fd);
    }

    // Reader process
    void posix_reader() {
    // Open existing shared memory segment
    int fd = shm_open(SHM_NAME, O_RDONLY, 0666);
    if (fd == -1) {
    perror("shm_open");
    exit(1);
    }

    // Map shared memory to process address space
    SharedData* shared_data = (SharedData*)mmap(NULL, SHM_SIZE,
    PROT_READ,
    MAP_SHARED, fd, 0);
    if (shared_data == MAP_FAILED) {
    perror("mmap");
    exit(1);
    }

    // Read from shared memory
    printf("Count: %d\n", shared_data->count);
    printf("Message: %s\n", shared_data->message);

    // Cleanup
    munmap(shared_data, SHM_SIZE);
    close(fd);
    shm_unlink(SHM_NAME); // Remove shared memory segment
    }

    /*
    * Example 2: System V Shared Memory
    * This example demonstrates the older System V IPC shared memory interface
    */

    #include <sys/ipc.h>
    #include <sys/shm.h>

    #define SHM_KEY 12345

    void sysv_writer() {
    // Create shared memory segment
    int shmid = shmget(SHM_KEY, SHM_SIZE, IPC_CREAT | 0666);
    if (shmid == -1) {
    perror("shmget");
    exit(1);
    }

    // Attach shared memory segment
    SharedData* shared_data = (SharedData*)shmat(shmid, NULL, 0);
    if (shared_data == (void*)-1) {
    perror("shmat");
    exit(1);
    }

    // Write to shared memory
    shared_data->count = 100;
    strcpy(shared_data->message, "Hello from System V shared memory!");

    // Detach shared memory
    shmdt(shared_data);
    }

    void sysv_reader() {
    // Get existing shared memory segment
    int shmid = shmget(SHM_KEY, SHM_SIZE, 0666);
    if (shmid == -1) {
    perror("shmget");
    exit(1);
    }

    // Attach shared memory segment
    SharedData* shared_data = (SharedData*)shmat(shmid, NULL, 0);
    if (shared_data == (void*)-1) {
    perror("shmat");
    exit(1);
    }

    // Read from shared memory
    printf("Count: %d\n", shared_data->count);
    printf("Message: %s\n", shared_data->message);

    // Cleanup
    shmdt(shared_data);
    shmctl(shmid, IPC_RMID, NULL); // Remove shared memory segment
    }

    /*
    * Example 3: Using shared memory with memory mapped files
    */

    void mmap_example() {
    // Create a file to back the shared memory
    int fd = open("shared_file.dat", O_CREAT | O_RDWR, 0666);
    if (fd == -1) {
    perror("open");
    exit(1);
    }

    // Set file size
    if (ftruncate(fd, SHM_SIZE) == -1) {
    perror("ftruncate");
    exit(1);
    }

    // Map file into memory
    SharedData* shared_data = (SharedData*)mmap(NULL, SHM_SIZE,
    PROT_READ | PROT_WRITE,
    MAP_SHARED, fd, 0);
    if (shared_data == MAP_FAILED) {
    perror("mmap");
    exit(1);
    }

    // Use the mapped memory
    shared_data->count = 200;
    strcpy(shared_data->message, "Hello from memory mapped file!");

    // Ensure changes are written to disk
    msync(shared_data, SHM_SIZE, MS_SYNC);

    // Cleanup
    munmap(shared_data, SHM_SIZE);
    close(fd);
    }

    int main() {
    // Example usage of POSIX shared memory
    if (fork() == 0) {
    posix_writer();
    exit(0);
    } else {
    sleep(1); // Ensure writer goes first
    posix_reader();
    }

    // Example usage of System V shared memory
    if (fork() == 0) {
    sysv_writer();
    exit(0);
    } else {
    sleep(1);
    sysv_reader();
    }

    // Example usage of memory mapped files
    mmap_example();

    return 0;
    }