Linux |
CentOS 5.3 |
|
shmdt(2) |
shmop, shmat, shmdt − Opérations sur la mémoire partagée. |
#include <sys/types.h> #include <sys/shm.h> void *shmat ( int shmid, const void * shmaddr, int shmflg); int shmdt (const void * shmaddr); |
shmat() attache le segment de mémoire partagée identifié par shmid au segment de données du processus appelant. L’adresse d’attachement est indiquée par shmaddr avec les critères suivants : |
Si shmaddr vaut NULL, le système essaye de trouver une adresse libre pour attacher le segment. Si shmaddr n’est pas NULL et si SHM_RND est indiqué dans shmflg, l’attachement a lieu à l’adresse shmaddr arrondie au multiple inférieur de SHMLBA. Sinon shmaddr doit être alignée sur une frontière de page, où l’attachement a lieu. |
Si SHM_RDONLY est indiqué dans shmflg, le segment est attaché en lecture seulement, et le processus doit disposer de la permission de lecture dessus. Sinon le segment est attaché en lecture et écriture et le processus doit disposer des deux permissions d’accès. Il n’y a pas de notion d’écriture seule pour les segments de mémoire partagée. L’option (spécifique à Linux) SHM_REMAP peut être ajoutée dans shmflg pour indiquer que la projection du segment doit remplacer une projection précédente dans l’intervalle commençant en shmaddr et s’étendant sur la taille du segment. (Normalement une erreur EINVAL se produirait si une projection existait déjà dans l’intervalle indiqué). Dans ce cas, shmaddr ne doit pas être NULL. La valeur brk(2) du processus appelant n’est pas altérée par l’attachement. Le segment est automatiquement détaché quand le processus se termine. Le même segment peut être attaché à la fois en lecture seule et en lecture/écriture. Il peut également être attaché en plusieurs endroits de l’espace d’adressage du processus. Si shmat() réussit, les membres de la structure shmid_ds (voir shmctl(2)) associée au segment de mémoire partagée sont mis à jour ainsi : |
shm_atime correspond à l’heure actuelle. shm_lpid contient le PID de l’appelant. shm_nattch est incrémenté de 1 détache le segment de mémoire partagée situe à l’adresse indiquée par shmaddr. Le segment doit être effectivement attaché, et l’adresse shmaddr doit être celle renvoyée précédemment par shmat(). |
Quand shmdt() réussit, les membres de la structure shmid_ds associée au segment de mémoire partagée sont mis à jour ainsi : |
shm_dtime correspond à l’heure actuelle. shm_lpid contient le PID de l’appelant. shm_nattch est décrémenté de 1. S’il devient nul, et si le segment est marqué pour destruction, il est effectivement détruit. |
fork() |
Après un fork() le fils hérite des segments de mémoire partagée. |
||
exec() |
Après un exec() tous les segments de mémoire partagée sont détachés (pas détruits). |
||
exit() |
Lors d’un exit() tous les segments de mémoire partagée sont détachés (pas détruits). |
S’il réussit, shmat() renvoie l’adresse d’attachement du segment de mémoire partagée. S’il échoue, il renvoie (void *) −1 et errno est remplie pour indiquer la cause de l’erreur. S’il réussit, shmdt() renvoie 0. S’il échoue, il renvoie −1, auquel cas errno contient le code d’erreur. |
shmat() : |
EACCES |
L’appelant n’a pas les permissions d’accès nécessaires pour l’attachement, et n’a pas la capacité CAP_IPC_OWNER. |
|
EINVAL |
shmid est invalide, shmaddr est mal alignée (c’est-à -dire pas alignée sur une page et SHM_RND n’a pas été spécifié, ou la valeur de shmaddr est invalide, ou échec d’attachement à brk(), ou SH_REMAP a été réclamé et shmaddr est NULL. |
|
ENOMEM |
Pas assez de mémoire pour le système. |
shmdt() : |
EINVAL |
Pas de segment de mémoire partagée attaché à l’adresse shmaddr ; ou shmaddr n’est pas alignée sur une frontière de page. |
Utiliser shmat() avec shmaddr égal à NULL est la manière conseillée, portable, d’attacher un segment de mémoire partagée. Soyez conscients que le segment attaché de cette manière peut l’être à des adresses différentes dans les différents processus. Ainsi, tout pointeur contenu dans la mémoire partagée doit être relatif (typiquement par rapport au début du segment) et pas absolu. Sous Linux, il est possible d’attacher un segment de mémoire partagée même s’il est déjà marqué pour être détruit. Toutefois, POSIX.1-2001 n’indique pas ce comportement et bien d’autres implémentations ne le supportent pas. Les paramètres système suivants influent sur shmat() : |
SHMLBA |
Multiple pour l’adresse de début de segment. Doit être aligné sur une frontière de page. Pour l’implémentation actuelle, SHMLBA à la même valeur que PAGE_SIZE. |
L’implémentation n’a pas de limite intrinsèque pour le nombre maximal de segments de mémoire partagée par processus. (SHMSEG). |
SVr4, POSIX.1-2001. Dans SVID 3 (ou peut être plutôt), le type de l’argument shmaddr a été modifié de en const void *, et le type de retour de shmat() de Ichar *" en void *. (Les bibliothèques Linux libc4 et libc5 avaient le prototype char * , la glibc 2 celui de void *). |
brk(2), mmap(2), shmctl(2), shmget(2), capabilities(7), svipc(7) |
Ce document est une traduction réalisée par Christophe Blaess <http://www.blaess.fr/christophe/> le 16 octobre 1996 et révisée le 14 août 2006. L’équipe de traduction a fait le maximum pour réaliser une adaptation française de qualité. La version anglaise la plus à jour de ce document est toujours consultable via la commande : « LANG=C man 2 shmop ». N’hésitez pas à signaler à l’auteur ou au traducteur, selon le cas, toute erreur dans cette page de manuel. |
shmdt(2) |