Memoria compartida del sistema 5

1. Introducción a la memoria compartida:

        La memoria compartida es el método más eficiente de comunicación entre procesos. Los procesos pueden leer y escribir directamente en la memoria sin ninguna copia de datos.
         Para intercambiar información entre múltiples procesos, el kernel reserva un área de memoria que el proceso que necesita acceder a ella puede asignar a su propio espacio de direcciones privado.
        El proceso puede leer y escribir directamente en esta área de memoria sin copiar los datos, lo que mejora enormemente la eficiencia.
        Dado que varios procesos comparten una sección de memoria, también deben depender de algún tipo de mecanismo de sincronización, como mutexes y semáforos.

2. Características de la memoria compartida:      

        2.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.2 Una cosa a tener en cuenta al utilizar 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.

3. Diagrama de marco:

4. Análisis API de memoria compartida:

    4.1 Crear u obtener memoria compartida:    
#include <sys/ipc.h>
#include <sys/shm.h>
int shmget(key_t key, size_t size, int shmflg);
功能:
     创建或获取共享内存
参数:
     1> key:密钥    一组16进制的地址
        1>自动获取:IPC_PRIVATE:系统自动创建分配共享内存
            弊端:永远都找不到同一块内存,不断创建新的共享内存,不采用
        2>手动获取:
            采用ftok函数
            #include <sys/types.h>
            #include <sys/ipc.h>
            key_t ftok(const char *pathname, int proj_id);
                  功能: 
                      手动创建或获取key 
                                    
                 参数: 
                      1>pathname:工程文件名(带路径)
                      2>proj_id :工程代号 
                                     
                 返回值: 
                       成功返回key 
                 失败返回-1,并设置错误码
                //只要参数不变化,总可以找到同一key

    2>size:共享内存大小
    3>shmflg:使用权限:
        IPC_CREAT|0666
返回值:
    成功返回shmid 
    失败返回-1,并设置错误码




ftok: Función: crea un identificador de memoria compartida único en el kernel para que el kernel pueda identificar una memoria compartida única, un semáforo o una cola de mensajes. 

 

 

        4.2 Mapeo de la memoria de contribución:
#include <sys/types.h>
#include <sys/shm.h>
void *shmat(int shmid, const void *shmaddr, int shmflg);
功能:
     将共享内存映射到用户空间(进程)
参数:
     1>shmid:共享内存ID 
     2>shmaddr:你想要映射到的地方:NULL  自行寻找
     3>shmflg:0 可读可写

返回值:
       成功返回映射到的地址
       失败返回(void *)-1,并设置错误码
        4.3 Desasignación
shmdt
#include <sys/types.h>
#include <sys/shm.h>
int shmdt(const void *shmaddr);
功能: 
    解除映射操作 
                    
参数: 
    shmaddr:需要解除的地址 
                    
返回值: 
      成功返回0
      失败返回-1,并设置错误码
        4.4 Eliminar memoria compartida
 4>删除共享内存 
    shmctl  --->共享内存操作 
    #include <sys/ipc.h>
    #include <sys/shm.h>
    int shmctl(int shmid, int cmd, struct shmid_ds *buf);
    功能: 
        对共享内存进行操作  
        PS:删除只是其中一环
                           
    参数: 
         1>shmid:需要操作的共享内存ID号 
         2>cmd:删除共享内存操作:
              IPC_RMID:删除共享内存 
                            
         3>buf:结构体指针:用来赋值的操作
              IPC_RMID:NULL 
                            
    返回值: 
             IPC_RMID:成功返回0 
             失败返回-1,并设置错误码

5. Verifique la memoria compartida en el sistema.

 ipcs -m 

6. Eliminar la memoria compartida en el sistema.

ipcrm -m 共享内存ID

7. Ejemplo de memoria compartida:

Escribe en un extremo:

#include <stdio.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
int main(){
    //创建密钥
    key_t key=ftok("pause.c",1);
    if(key<0){
        perror("ftok");
        return -1;
    }
    
    printf("key:%#x\n",key);
    
    //1>创建或获取共享内存
    int shmid=shmget(key,200,IPC_CREAT|0666);
    //int shmid=shmget(IPC_PRIVATE,200,IPC_CREAT|0666);
    if(shmid<0){
        perror("shmget");
        return -1;
    }
    printf("共享内存ID号为:%d\n",shmid);
    
    //2>将共享内存映射到用户空间
    void *addr=shmat(shmid,NULL,0);
    if(addr==(void *)-1){
        perror("shmat");
        return -1;
    }
    char *p=(char *)addr;//将万能指针型转化为char * 
    printf("进程的地址为:%p\n",p);
    
    //3>解除映射 
    int ret=shmdt(addr);
    if(ret<0){
        perror("shmdt");
        return -1;  
    }
    
    //4>删除共享内存 
    ret=shmctl(shmid,IPC_RMID,NULL);
    if(ret<0){
        perror("shmctl");
        return -1;  
    }
    
    //通信?
    //while(1){
    scanf("%s",p);//此时,p为野指针,发生段错误 
    //}
    return 0;
}

Un extremo dice:

#include <stdio.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
int main(){
    //创建密钥
    key_t key=ftok("pause.c",1);
    if(key<0){
        perror("ftok");
        return -1;
    }
    
    printf("key:%#x\n",key);
    
    
    //1>创建或获取共享内存
    int shmid=shmget(key,200,IPC_CREAT|0666);
    //int shmid=shmget(IPC_PRIVATE,200,IPC_CREAT|0666);//最好不使用
    if(shmid<0){
        perror("shmget");
        return -1;
    }
    printf("共享内存ID号为:%d\n",shmid);
    
    
    //2>将共享内存映射到用户空间
    void *addr=shmat(shmid,NULL,0);
    if(addr==(void *)-1){
        perror("shmat");
        return -1;
    }
    char *p=(char *)addr;//将万能指针型转化为char * 
    printf("进程的地址为:%p\n",p);
   
    //3>通信?
    while(1){//共享内存是不会阻塞的
    printf("%s\n",p);
    }
    return 0;

Resumir:


          Memoria compartida: use el área de memoria para mapear el espacio de dos procesos. Los dos procesos transfieren datos a través de la memoria, ingresan directamente al área de memoria y salen directamente. Es el más eficiente porque cuando se opera el área de memoria, si la operación no es riguroso, los errores encontrados en los segmentos pueden ser relativamente comunes. El área de memoria es entrada y salida directamente, por lo que no existe ningún concepto de bloqueo 
            mientras (1) // no está disponible y requiere otros medios.

Supongo que te gusta

Origin blog.csdn.net/apple_71040140/article/details/132511979
Recomendado
Clasificación