GNU/Linux >> Tutoriels Linux >  >> Linux

Comment utiliser la mémoire partagée avec Linux en C

Voici un exemple de mémoire partagée :

#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;
}

Étapes :

  1. Utilisez ftok pour convertir un nom de chemin et un identifiant de projet en une clé System V IPC

  2. Utilisez shmget qui alloue un segment de mémoire partagée

  3. Utilisez shmat pour attacher le segment de mémoire partagée identifié par shmid à l'espace d'adressage du processus appelant

  4. Faire les opérations sur la zone mémoire

  5. Détacher en utilisant shmdt


Il existe deux approches :shmget et mmap . Je vais parler de mmap , car il est plus moderne et flexible, mais vous pouvez jeter un œil à man shmget (ou ce tutoriel) si vous préférez utiliser les outils à l'ancienne.

Le mmap() La fonction peut être utilisée pour allouer des tampons de mémoire avec des paramètres hautement personnalisables pour contrôler l'accès et les autorisations, et pour les sauvegarder avec un stockage de système de fichiers si nécessaire.

La fonction suivante crée un tampon en mémoire qu'un processus peut partager avec ses enfants :

#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);
}

Voici un exemple de programme qui utilise la fonction définie ci-dessus pour allouer un tampon. Le processus parent écrira un message, fork, puis attendra que son enfant modifie le tampon. Les deux processus peuvent lire et écrire dans la mémoire partagée.

#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. Comment utiliser BusyBox sous Linux

  2. Comment utiliser la commande Linux Hexdump avec des exemples pratiques

  3. Comment utiliser la commande Su sous Linux

  4. Commande SCP sous Linux :comment l'utiliser, avec des exemples

  5. Comment supprimer une utilisation non root avec UID 0 sous Linux

Comment utiliser la commande who sous Linux avec des exemples

Commande d'alias Linux :comment l'utiliser avec des exemples

Comment vérifier la mémoire partagée Linux à l'aide de la commande ipcs

Comment utiliser la commande Linux gunzip avec des exemples

Comment utiliser la commande Linux rm avec des exemples

Comment utiliser la commande Sleep sous Linux :expliqué avec des exemples