GNU/Linux >> Tutoriales Linux >  >> Linux

Cómo usar la memoria compartida con Linux en C

Aquí hay un ejemplo de memoria compartida:

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

Pasos:

  1. Utilice ftok para convertir un nombre de ruta y un identificador de proyecto en una clave System V IPC

  2. Use shmget que asigna un segmento de memoria compartida

  3. Use shmat para adjuntar el segmento de memoria compartida identificado por shmid al espacio de direcciones del proceso de llamada

  4. Haz las operaciones en el área de memoria

  5. Separar usando shmdt


Hay dos enfoques:shmget y mmap . Hablaré de mmap , ya que es más moderno y flexible, pero puedes echarle un vistazo a man shmget (o este tutorial) si prefiere usar las herramientas de estilo antiguo.

El mmap() La función se puede utilizar para asignar búferes de memoria con parámetros altamente personalizables para controlar el acceso y los permisos, y para respaldarlos con el almacenamiento del sistema de archivos si es necesario.

La siguiente función crea un búfer en memoria que un proceso puede compartir con sus hijos:

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

El siguiente es un programa de ejemplo que utiliza la función definida anteriormente para asignar un búfer. El proceso principal escribirá un mensaje, se bifurcará y luego esperará a que su hijo modifique el búfer. Ambos procesos pueden leer y escribir en la memoria compartida.

#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. Cómo uso Vagrant con libvirt

  2. Cómo usar BusyBox en Linux

  3. Cómo uso cron en Linux

  4. Cómo eliminar un uso no root con UID 0 en Linux

  5. Cómo usar la exportación con Python en Linux

Cómo usar el comando who en Linux con ejemplos

Comando alias de Linux:cómo usarlo con ejemplos

Cómo verificar la memoria compartida de Linux usando el comando ipcs

Cómo usar el comando gunzip de Linux con ejemplos

Cómo usar el comando rm de Linux con ejemplos

Cómo usar el comando de suspensión en Linux:explicado con ejemplos