Scroll to navigation

SHMOP(2) Manuel du programmeur Linux SHMOP(2)

NOM

shmat, shmdt - Opérations sur la mémoire partagée System V

SYNOPSIS

#include <sys/types.h>
#include <sys/shm.h>
void *shmat(int shmid, const void *shmaddr, int shmflg);
int shmdt(const void *shmaddr);

DESCRIPTION

shmat()

La fonction shmat() attache le segment de mémoire partagée System V 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 choisit une adresse (non utilisée) alignée sur la page convenant pour attacher le segment.
  • Si shmaddr n'est pas NULL et si SHM_RND est indiqué dans shmflg, l'attachement a lieu à l'adresse égale à 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.

En plus de SHM_RND, les attributs suivants peuvent être indiqués dans le paramètre de masque shmflg :

Autoriser l'exécution du contenu du segment. L'appelant doit disposer du droit d'exécution sur le segment.
Attacher le segment en lecture seule. Le processus doit disposer de la permission de lecture dessus. Si cet attribut n'est pas indiqué, 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.
Cet attribut indique 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 devrait se produire si une projection existe 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.

Quand shmat() réussit, les membres de la structure shmid_ds associée au segment de mémoire partagée (consultez shmctl(2)) 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.

shmdt()

La fonction shmdt() détache le segment de mémoire partagée situé à 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 l'appel 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 par le système :

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.

VALEUR RENVOYÉE

S'il réussit, shmat() renvoie l'adresse d'attachement du segment de mémoire partagée. En cas d'échec (void *) -1 est renvoyé, et errno est définie pour préciser l'erreur.

S'il réussit, shmdt() renvoie 0. En cas d'échec, -1 est renvoyé et errno est positionné pour indiquer l'erreur.

ERREURS

Quand shmat() échoue, errno prend l'une des valeurs suivantes :

Le processus appelant n'a pas les permissions d'accès nécessaires pour ce type d'attachement et n'a pas la capacité CAP_IPC_OWNER dans l'espace de noms utilisateur qui gère son espace de noms IPC.
shmid pointe sur un segment détruit.
La valeur shmid n'est pas valable, mal alignée (c'est-à-dire pas alignée sur une page et SHM_RND n'a pas été précisé) ou la valeur shmaddr n'est pas valable, ou ne peut pas être attaché à shmaddr, ou SHM_REMAP a été réclamé et shmaddr est NULL.
Pas assez de mémoire pour le descripteur ou pour les tables de pages.

Quand shmdt() échoue, errno prend l'une des valeurs suivantes :

Aucun segment de mémoire partagée n'est attaché à l'adresse shmaddr, ou bien shmaddr n'est pas aligné une limite de page.

CONFORMITÉ

POSIX.1-2001, POSIX.1-2008, SVr4.

Dans SVID 3 (ou peut être auparavant), le type de l'argument shmaddr a été modifié de char * en const void *, et le type de retour de shmat() de char * en void *.

NOTES

Après un fork(2), l'enfant hérite des segments de mémoire partagée attachés.

Après un execve(2), tous les segments de mémoire partagée sont détachés du (pas détruits).

Lors d'un _exit(2), tous les segments de mémoire partagée sont détachés du processus (pas détruits).

Utiliser shmat() avec shmaddr égale à NULL est la manière conseillée et 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 (habituellement par rapport à l'adresse de départ du segment) et pas absolu.

Sous Linux, il est possible d'attacher un segment de mémoire partagée qui est déjà marqué pour effacement. Cependant, ce comportement n'est pas décrit par POSIX.1 et beaucoup d'autres implémentations ne le permettent pas.

Le paramètre système suivant influe sur shmat() :

Multiple d’adresse pour limite basse de segment. Lors d’une indication explicite d’adresse d’attache dans un appel shmat(), l’appelant devrait s’assurer que l’adresse est un multiple de cette valeur. Cela est nécessaire sur certaines architectures, afin de s’assurer soit de bonne performances du cache de processeur, soit que différentes attaches du même segment ont des vues cohérentes dans le cache du processeur. SHMLBA est normalement un multiple de la taille de page du système (sur de nombreuses architectures Linux, SHMLBA est identique à la taille de page du système).

L'implémentation ne met pas de limite intrinsèque par processus pour le nombre maximal de segments de mémoire partagée (SHMSEG).

VOIR AUSSI

brk(2), mmap(2), shmctl(2), shmget(2), capabilities(7), shm_overview(7), svipc(7)

COLOPHON

Cette page fait partie de la publication 4.16 du projet man-pages Linux. Une description du projet et des instructions pour signaler des anomalies et la dernière version de cette page peuvent être trouvées à l'adresse https://www.kernel.org/doc/man-pages/.

TRADUCTION

La traduction française de cette page de manuel a été créée par Christophe Blaess <https://www.blaess.fr/christophe/>, Stéphan Rafin <stephan.rafin@laposte.net>, Thierry Vignaud <tvignaud@mandriva.com>, François Micaux, Alain Portal <aportal@univ-montp2.fr>, Jean-Philippe Guérard <fevrier@tigreraye.org>, Jean-Luc Coulon (f5ibh) <jean-luc.coulon@wanadoo.fr>, Julien Cristau <jcristau@debian.org>, Thomas Huriaux <thomas.huriaux@gmail.com>, Nicolas François <nicolas.francois@centraliens.net>, Florentin Duneau <fduneau@gmail.com>, Simon Paillard <simon.paillard@resel.enst-bretagne.fr>, Denis Barbier <barbier@debian.org>, David Prévot <david@tilapin.org> et Jean-Philippe MENGUAL <jpmengual@debian.org>

Cette traduction est une documentation libre ; veuillez vous reporter à la GNU General Public License version 3 concernant les conditions de copie et de distribution. Il n'y a aucune RESPONSABILITÉ LÉGALE.

Si vous découvrez un bogue dans la traduction de cette page de manuel, veuillez envoyer un message à debian-l10n-french@lists.debian.org.

15 septembre 2017 Linux