NOMBRE¶
shmop - operaciones con memoria compartida
SINOPSIS¶
#include <sys/types.h>
#include <sys/shm.h>
void *shmat(int shmid, const void
*shmaddr, int shmflg);
int shmdt(const void *shmaddr);
DESCRIPCIÓN¶
La función
shmat pega el segmento de memoria compartida identificada
por
shmid al espacio de direcciones del proceso que llama a la
función. La dirección del pegado se especifica en
shmaddr
según uno de los criterios siguientes:
Si
shmaddr es
NULL, el sistema escoge una dirección adecuada
(sin utilizar) en donde pegar el segmento.
Si
shmaddr no es
NULL y
SHM_RND está activado en
shmflg, el pegado ocurre en la dirección igual al redondeo por
abajo de
shmaddr al múltiplo más cercano de
SHMLBA. De
otro modo,
shmaddr debe ser una dirección alineada de una
página en la cual ocurra el pegado.
Si
SHM_RDONLY está activado en
shmflg, el segmento se pega
para lectura y el proceso debe tener permiso de lectura en el segmento. De
otro modo el segmento se pega para lectura y escritura y debe tener permisos
de lectura y escritura en el segmento. No existe la noción de un segmento
de memoria compartida de escritura exclusiva.
La bandera (específica de Linux)
SHM_REMAP puede ser activada en
shmflg para indicar que la correspondencia del segmento debería
reemplazar cualquier correspondencia existente en el rango que comienza en
shmaddr y continua hasta el tamaño del segmento. (Normalmente se
produciría un error
EINVAL si ya existiera una correspondencia en
este rango de direcciones.) En este caso,
shmaddr no debe ser
NULL. El valor de
brk del proceso que llama a la función no
se altera por el pegado. El segmento se despegará automáticamente
cuendo el proceso se acabe. El mismo segmento puede ser pegaado como de
lectura y de lectura-escritura, y más de una vez, en el espacio de
direcciones del proceso.
Tras una llamada exitosa a
shmat el sistema actualiza los miembros de la
estructura
shmid_ds asociada al segmento de memoria compartida como
sigue:
- shm_atime toma el valor de la hora actual.
- shm_lpid toma el valor del PID del proceso
llamador.
- shm_nattch se incrementa en uno.
Observe que el pegado tiene éxito también si el segmento de memoria
compartida se marca como para ser borrado.
La función
shmdt despega el segmento de memoria compartida
localizado en la dirección especificada por
shmaddr del espacio de
direcciones del proceso invocador. El segmento a ser despegado debe estar
actualmente pegado con
shmaddr igual al valor devuelto por su llamada
de pegado
shmat.
Tras una llamada exitosa a
shmdt el sistema actualiza los miembros de la
estructura
shmid_ds asociada al segmento de memoria compartida como
sigue:
- shm_dtime toma el valor de la hora actual.
- shm_lpid toma el valor del PID del proceso
llamador.
- shm_nattch se decrementa en uno. Si llega a 0 y el
segmento está marcado para ser borrado, el segmento se borra.
La región ocupada en el espacio de usuario del proceso llamador es
desasociada.
LLAMADAS AL SISTEMA¶
- fork()
- Después de un fork() el hijo hereda los
segmentos de memoria compartidos pegados.
- exec()
- Tras un exec() todos los segmentos de memoria
compartida pegados son despegados del proceso.
- exit()
- Tras exit() todos los segmentos de memoria
compartida pegados son despegados del proceso.
VALOR DEVUELTO¶
En caso de fallo ambas funciones devuelven
-1 con
errno indicando
el error. En caso de éxito
shmat devuelve la dirección del
segmento de memoria compartido pegado, y
shmdt devuelve
0.
ERRORES¶
Cuando
shmat falla
errno tiene uno de entre los siguientes
valores:
- EACCES
- El proceso llamador no tiene permisos de acceso para el
tipo de pegado pedido.
- EINVAL
- Valor de shmid inválido, no alineado (i.e., sin
alineamiento de página y SHM_RND no se especificó), o
valor de shmaddr inválido, o pegado fallido en brk, o
se especificó SHM_REMAP y shmaddr era NULL.
- ENOMEM
- No se pudo reservar memoria para el descriptor o para las
tablas de página.
La función
shmdt puede fallar sólo si no hay segmento de
memoria compartida pegada en
shmaddr, en cuyo caso al regresar
errno tendrá el valor
EINVAL.
OBSERVACIONES¶
Usar
shmat con
shmaddr igual a
NULL es la manera portable y
preferida de pegar un segmento de memoria compartida. Sea consciente de que el
segmento de memoria compartida pegado de esta manera puede ser pegado en
diferentes direcciones en diferentes procesos. Por consiguiente, cualquier
puntero mantenido dentro de la memoria compartida debe ser hecho relativo
(habitualmente a la dirección de comienzo del segmento), en lugar de
absoluto.
El siguiente parámetro del sistema afecta a
shmat:
- SHMLBA
- Dirección del límite inferior del segmento. Debe
estar alineado a página. Para la implementación actual el valor
de SHMBLA es PAGE_SIZE.
La implementación no tiene un límite intrínseco para el
número máximo de segmentos de memoria compartida por proceso
(
SHMSEG).
SVr4, SVID. SVr4 documenta una condición de error adicional EMFILE. En
SVID-v4, el tipo del argumento
shmaddr se cambió de
char *
a
const void *, y el tipo del valor devuelto por
shmat() de
char * a
void *. (Linux libc4 y libc5 poseen los prototipos
char *. glibc2 posee
void *.)
VÉASE TAMBIÉN¶
brk(2),
ipc(5),
mmap(2),
shmctl(2),
shmget(2)