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
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.