GNU/Linux >> LINUX-Kenntnisse >  >> Linux

So verwenden Sie Shared Memory mit Linux in C

Hier ist ein Beispiel für Shared Memory :

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>

#define SHM_SIZE 1024  /* make it a 1K shared memory segment */

int main(int argc, char *argv[])
{
    key_t key;
    int shmid;
    char *data;
    int mode;

    if (argc > 2) {
        fprintf(stderr, "usage: shmdemo [data_to_write]\n");
        exit(1);
    }

    /* make the key: */
    if ((key = ftok("hello.txt", 'R')) == -1) /*Here the file must exist */ 
{
        perror("ftok");
        exit(1);
    }

    /*  create the segment: */
    if ((shmid = shmget(key, SHM_SIZE, 0644 | IPC_CREAT)) == -1) {
        perror("shmget");
        exit(1);
    }

    /* attach to the segment to get a pointer to it: */
    if ((data = shmat(shmid, NULL, 0)) == (void *)-1) {
        perror("shmat");
        exit(1);
    }

    /* read or modify the segment, based on the command line: */
    if (argc == 2) {
        printf("writing to segment: \"%s\"\n", argv[1]);
        strncpy(data, argv[1], SHM_SIZE);
    } else
        printf("segment contains: \"%s\"\n", data);

    /* detach from the segment: */
    if (shmdt(data) == -1) {
        perror("shmdt");
        exit(1);
    }

    return 0;
}

Schritte :

  1. Verwenden Sie ftok, um einen Pfadnamen und eine Projektkennung in einen System-V-IPC-Schlüssel umzuwandeln

  2. Verwenden Sie shmget, das ein gemeinsames Speichersegment zuweist

  3. Verwenden Sie shmat, um das von shmid identifizierte Shared-Memory-Segment an den Adressraum des aufrufenden Prozesses anzuhängen

  4. Führen Sie die Operationen im Speicherbereich aus

  5. Trennen mit shmdt


Es gibt zwei Ansätze:shmget und mmap . Ich werde über mmap sprechen , da es moderner und flexibler ist, aber Sie können einen Blick auf man shmget werfen (oder dieses Tutorial), wenn Sie lieber die Tools im alten Stil verwenden möchten.

Die mmap() -Funktion kann verwendet werden, um Speicherpuffer mit hochgradig anpassbaren Parametern zuzuweisen, um Zugriff und Berechtigungen zu steuern und sie bei Bedarf mit Dateisystemspeicher zu sichern.

Die folgende Funktion erstellt einen In-Memory-Puffer, den ein Prozess mit seinen Kindern teilen kann:

#include <stdio.h>
#include <stdlib.h>
#include <sys/mman.h>

void* create_shared_memory(size_t size) {
  // Our memory buffer will be readable and writable:
  int protection = PROT_READ | PROT_WRITE;

  // The buffer will be shared (meaning other processes can access it), but
  // anonymous (meaning third-party processes cannot obtain an address for it),
  // so only this process and its children will be able to use it:
  int visibility = MAP_SHARED | MAP_ANONYMOUS;

  // The remaining parameters to `mmap()` are not important for this use case,
  // but the manpage for `mmap` explains their purpose.
  return mmap(NULL, size, protection, visibility, -1, 0);
}

Das Folgende ist ein Beispielprogramm, das die oben definierte Funktion verwendet, um einen Puffer zuzuweisen. Der übergeordnete Prozess schreibt eine Nachricht, verzweigt sich und wartet dann darauf, dass sein untergeordneter Prozess den Puffer ändert. Beide Prozesse können den Shared Memory lesen und schreiben.

#include <string.h>
#include <unistd.h>

int main() {
  char parent_message[] = "hello";  // parent process will write this message
  char child_message[] = "goodbye"; // child process will then write this one

  void* shmem = create_shared_memory(128);

  memcpy(shmem, parent_message, sizeof(parent_message));

  int pid = fork();

  if (pid == 0) {
    printf("Child read: %s\n", shmem);
    memcpy(shmem, child_message, sizeof(child_message));
    printf("Child wrote: %s\n", shmem);

  } else {
    printf("Parent read: %s\n", shmem);
    sleep(1);
    printf("After 1s, parent read: %s\n", shmem);
  }
}

Linux
  1. Wie ich Vagrant mit libvirt verwende

  2. So verwenden Sie BusyBox unter Linux

  3. Wie ich Cron unter Linux verwende

  4. So verwenden Sie den Rmmod-Befehl unter Linux mit Beispielen

  5. So löschen Sie eine Nicht-Root-Nutzung mit UID 0 in Linux

So verwenden Sie den who-Befehl in Linux mit Beispielen

Linux-Alias-Befehl:Verwendung mit Beispielen

So überprüfen Sie den gemeinsam genutzten Linux-Speicher mit dem ipcs-Befehl

So verwenden Sie den Gunzip-Befehl unter Linux mit Beispielen

So verwenden Sie den Linux-rm-Befehl mit Beispielen

So verwenden Sie den Sleep-Befehl unter Linux:Erklärt mit Beispielen