[Memoria compartida] Memoria compartida y comunicación de procesos

Tabla de contenido

1. Descripción general de la memoria compartida

2. Operaciones de memoria compartida

1) Obtener un identificador de almacenamiento compartido: función shmget

2) Mapeo de memoria compartida (adjuntar): función shmat

3) Separar mapeo de memoria compartida (separar): función shmdt

4) Control de memoria compartida: función shmctl

Resumir:


1. Descripción general de la memoria compartida

        La memoria compartida permite que dos o más procesos compartan un área de almacenamiento determinada.

Características de la memoria compartida:

1) La memoria compartida es la forma más rápida de compartir datos entre procesos.

        Cuando un proceso escribe datos en un área de memoria compartida, todos los procesos que comparten esta área de memoria pueden ver inmediatamente el contenido.

2) Lo que se debe tener en cuenta al usar memoria compartida es la exclusión mutua del acceso a un área de almacenamiento determinada entre múltiples procesos.

        Si un proceso está escribiendo datos en el área de memoria compartida, otros procesos no deben leer ni escribir los datos hasta que complete esta operación.

Diagrama de memoria compartida:

        La memoria compartida es el método de comunicación entre procesos más eficiente. La razón es que el proceso opera directamente en la memoria física y asigna la dirección física al proceso del usuario. Por lo tanto, siempre que se realice la operación en su dirección, la dirección física es operado directamente.

2. Operaciones de memoria compartida

Las limitaciones de la memoria compartida en ubuntu12.04 son las siguientes:

  • Número mínimo de bytes en memoria compartida: 1
  • Número máximo de bytes en el área de almacenamiento compartido: 32 M
  • Número máximo de áreas de memoria compartida: 4096
  • El número máximo de áreas de almacenamiento compartido que cada proceso puede asignar: 4096

Utilice comandos de shell para operar la memoria compartida:

Ver memoria compartida: ipcs -m

Eliminar memoria compartida: ipcrm -m shmid

1) Obtener un identificador de almacenamiento compartido: función shmget

función shmget:

#incluir<sys/ipc.h>

#incluir<sys/shm.h>

int shmget(key_t clave, size_t tamaño, int shmflg);

Función: Crear una memoria compartida

parámetro:

        clave: valor clave, el valor clave único determina la memoria compartida única

        tamaño: el tamaño de la memoria compartida creada

        shmflg: permisos de acceso a memoria compartida

                        Generalmente IPC_CREAT | 0777

valor de retorno:

        Éxito: ID de memoria compartida

        Fallo: -1 

Ejemplo de código:

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

int main()
{
    key_t key;
    if ((key = ftok(".", 100)) == -1)
    {
        perror("fail to ftok");
        exit(1);
    }
    int shmid;
    if ((shmid = shmget(key, 500, IPC_CREAT | 0666)) == -1)
    {
        perror("fail to shmget");
        exit(1);
    }

    printf("shmid = %d\n", shmid);
    system("ipcs -m");

    return 0;
}

Captura de pantalla de ejecución:

2) Mapeo de memoria compartida (adjuntar): función shmat

función shmat:

#incluir<sys/types.h>

#incluir<sys/shm.h>

void *shmat(int shmid, const void *shmaddr, int shmflg);

Función: Mapa de memoria compartida

parámetro:

        shmid: ID de memoria compartida

        shmaddr: dirección asignada, establecida en NULL para la asignación automática por parte del sistema

        shmflg: bit de bandera

                0: la memoria compartida tiene permisos de lectura y escritura

                SHM_RDONLY: solo lectura

valor de retorno:

        Éxito: dirección asignada

        Fallo: -1

3) Separar mapeo de memoria compartida (separar): función shmdt

función shmdt:

#incluir<sys/types.h>

#incluir<sys/shm.h>

int shmdt(const void *shmaddr);

Función:

        Desasignar memoria compartida

parámetro:

        shmaddr: dirección asignada, valor de retorno de shmat

valor de retorno:

        Éxito: 0

        Fallo: -1 

Ejemplos de código de asignación y desasignación de memoria compartida: 

escribir.c

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

int main()
{
    key_t key;
    if ((key = ftok(".", 100)) == -1)
    {
        perror("fail to ftok");
        exit(1);
    }
    int shmid;
    if ((shmid = shmget(key, 500, IPC_CREAT | 0666)) == -1)
    {
        perror("fail to shmget");
        exit(1);
    }

    char* text;
    if ((text = shmat(shmid, NULL, 0)) == (void*)-1)
    {
        perror("fail to shmat");
        exit(1);
    }
    //写入
    strcpy(text, "hello world");
    if (shmdt(text) == -1)
    {
        perror("fail to text");
        exit(1);
    }
    system("ipcs -m");
    return 0;
}

leer.c

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

int main()
{
    //创建共享内存
    key_t key;
    if ((key = ftok(".", 100)) == -1)
    {
        perror("fail to ftok");
        exit(1);
    }
    int shmid;
    if ((shmid = shmget(key, 500, IPC_CREAT | 0666)) == -1)
    {
        perror("fail to shmget");
        exit(1);
    }

    //      system("ipcs -m");
    //映射
    char* text;
    if ((text = shmat(shmid, NULL, 0)) == (void*)-1)
    {
        perror("fail to shmat");
        exit(1);
    }
    printf("text = %s\n", text);
    //解除映射
    if (shmdt(text) == -1)
    {
        perror("fail to shmdt");
        exit;
    }
    system("ipcs -m");
    return 0;
}

Captura de pantalla de ejecución: 

 

4) Control de memoria compartida: función shmctl

función shmctl:

#incluir<sys/ipc.h>

#incluir<sys/shm.h>

int shmctl(int shmid, int cmd, estructura shmid_ds *buf);

Función:

        Establecer u obtener las propiedades de la memoria compartida.

parámetro:

        shmid: ID de memoria compartida

        cmd: comando para realizar operaciones

                IPC_STAT Obtiene los atributos de la memoria compartida.

                IPC_SET establece las propiedades de la memoria compartida.

                IPC_RMID eliminar memoria compartida

        shmid_ds: estructura de atributos de la memoria compartida

valor de retorno:

        Éxito: 0

        Fallo: -1

Ejemplo de código:

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

int main()
{
    key_t key;
    if ((key = ftok(".", 100)) == -1)
    {
        perror("fail to ftok");
        exit(1);
    }
    int shmid;
    if ((shmid = shmget(key, 500, IPC_CREAT | 0666)) == -1)
    {
        perror("fail to shmget");
        exit(1);
    }

    printf("shmid = %d\n", shmid);
    //删除共享内存
    if (shmctl(shmid, IPC_RMID, NULL) == -1)
    {
        perror("fial to shmid");
        exit(1);
    }
    system("ipcs -m");
    return 0;
}

Captura de pantalla de ejecución:

Resumir:

        Como mecanismo eficiente de comunicación entre procesos, la memoria compartida juega un papel importante en un entorno multiproceso con sus ventajas únicas. Permite que múltiples procesos accedan directamente a la misma área de memoria, logrando así compartir e intercambiar datos rápidamente y mejorar significativamente el rendimiento del sistema . Sin embargo, esto también plantea desafíos de sincronización de datos y control de concurrencia. Necesitamos combinar bloqueos, semáforos y otras tecnologías de sincronización para resolver estos problemas.

        En general, la memoria compartida es una herramienta poderosa y flexible, pero debe usarse con cuidado y eficacia para garantizar la corrección y estabilidad del programa.

Supongo que te gusta

Origin blog.csdn.net/crr411422/article/details/131421891
Recomendado
Clasificación