shmget - Allouer un segment de mémoire partagée
System V
Bibliothèque C standard (libc, -lc)
#include <sys/shm.h>
int shmget(key_t key, size_t size, int shmflg);
shmget() renvoie l'identifiant du segment de mémoire
partagée System V associé à la valeur de
l'argument key. Il peut être utilisé soit pour obtenir
l'identifiant d'un segment de mémoire partagée
précédemment créé (quand shmflg vaut
zéro et quand key n'a pas la valeur IPC_PRIVATE), soit
pour créer un nouvel ensemble.
Un nouveau segment mémoire partagée, de taille
size arrondie au multiple supérieur de PAGE_SIZE, est
créé si key a la valeur IPC_PRIVATE ou si
key n'est pas IPC_PRIVATE, aucun segment de mémoire
partagée ne correspondant à key n'existe, et si
IPC_CREAT est indiqué dans shmflg.
Si shmflg contient à la fois les attributs
IPC_CREAT et IPC_EXCL, et si un segment de mémoire
partagée est déjà associé à key,
shmget() échoue avec le code d'erreur EEXIST. Cela est
similaire au comportement de open(2) avec la combinaison O_CREAT |
O_EXCL.
shmflg est composé de :
- IPC_CREAT
- Créer un nouveau segment. Sinon shmget() recherche le
segment associé à key et vérifie que
l'appelant a la permission d'y accéder.
- IPC_EXCL
- Cet attribut est utilisé avec IPC_CREAT pour garantir que
cet appel créé le segment. Si le segment existe
déjà, l'appel échoue.
- SHM_HUGETLB
(depuis Linux 2.6)
- Allouer le segment en utilisant des pages immenses. Consultez le fichier
Documentation/admin-guide/mm/hugetlbpage.rst dans les sources du
noyau Linux pour plus d'informations.
- SHM_HUGE_2MB,
SHM_HUGE_1GB (depuis Linux 3.8)
- Utilisé avec SHM_HUGETLB pour sélectionner des
tailles de page hugetlb alternatives (respectivement 2 Mo et
1 Go) sur les systèmes qui prennent en charge plusieurs
tailles de page hugetlb.
- Plus généralement, la taille de page immense
désirée peut être configurée en encodant le
logarithme de base 2 de la taille de la page désirée
dans les six bits situés à la position
SHM_HUGE_SHIFT. Ainsi, les deux constantes ci-dessus sont
définies comme :
-
#define SHM_HUGE_2MB (21 << SHM_HUGE_SHIFT)
#define SHM_HUGE_1GB (30 << SHM_HUGE_SHIFT)
- Pour plus de détails, consultez le point sur les constantes du
même nom dans mmap(2).
- SHM_NORESERVE
(depuis Linux 2.6.15)
- Cet attribut a le même objet que l'attribut MAP_NORESERVE de
mmap(2). Ne pas réserver d'espace de swap pour ce segment.
Lorsque de l'espace en swap est réservé, le système
garantit qu'il sera possible de modifier le segment. Lorsque l'espace en
swap n'est pas réservé, on peut recevoir SIGSEGV lors
d'une écriture si la mémoire physique est pleine. Consultez
aussi la discussion du fichier /proc/sys/vm/overcommit_memory dans
proc(5).
En plus des attributs ci-dessus, les 9 bits de poids faible
de shmflg indiquent les permissions pour le propriétaire, le
groupe et les autres. Ces bits ont le même format et la même
signification que l'argument mode de open(2). Actuellement la
permission d'exécution n'est pas utilisée par le
système.
Si un nouveau segment de mémoire partagée est
créé, le système initialise son contenu à
zéro, et la structure shmid_ds (consultez shmctl(2))
est associée au segment comme suit :
- shm_perm.cuid et shm_perm.uid contiennent l'UID effectif de
l'appelant.
- shm_perm.cgid et shm_perm.gid contiennent le GID effectif de
l'appelant.
- Les 9 bits de poids faible de shm_perm.mode contiennent les
9 bits de poids faible de shmflg.
- shm_segsz prend la valeur size.
- shm_lpid, shm_nattch, shm_atime et shm_dtime
sont mis à 0.
- shm_ctime contient l'heure actuelle.
Si le segment de mémoire existe déjà, les
permissions d'accès sont vérifiées, et un
contrôle a lieu pour voir s'il est marqué pour
destruction.
En cas de succès, un identifiant de mémoire
partagée valide est renvoyé. En cas d'erreur, -1 est
renvoyé et errno contient le code d'erreur.
- EACCES
- L'utilisateur n'a pas le droit d'accès au segment de mémoire
partagé et il n'a pas la capacité CAP_IPC_OWNER dans
l'espace de noms utilisateur qui gère son espace de noms IPC.
- EEXIST
- IPC_CREAT et IPC_EXCL étaient indiqués dans
shmflg, mais un segment de mémoire partagé
associé à key existe déjà.
- EINVAL
- Un nouveau segment devait être créé et size
est inférieur à SHMMIN ou supérieur à
SHMMAX.
- EINVAL
- Un segment associé à key existe, mais sa taille est
inférieure à size.
- ENFILE
- La limite du nombre total de fichiers ouverts pour le système
entier a été atteinte.
- ENOENT
- Aucun segment n'est associé à key, et
IPC_CREAT n'était pas indiqué.
- ENOMEM
- Pas assez de mémoire pour allouer le segment.
- ENOSPC
- Tous les identifiants de mémoire partagée sont
utilisés (SHMMNI), ou l'allocation d'un segment
partagé de taille size dépasserait les limites de
mémoire partagée du système (SHMALL).
- EPERM
- L'attribut SHM_HUGETLB est indiqué, mais l'appelant n'est
pas privilégié (ne possède pas la capacité
CAP_IPC_LOCK) et il n'est pas membre du groupe
sysctl_hugetlb_shm_group ; voir la description de
/proc/sys/vm/sysctl_hugetlb_shm_group dans proc(5).
POSIX.1-2001, POSIX.1-2008, SVr4.
SHM_HUGETLB et SHM_NORESERVE sont spécifiques
à Linux.
IPC_PRIVATE n'est pas une option mais une valeur de type
key_t. Si cette valeur spéciale est utilisée comme
clé, l'appel système ignore tout sauf les 9 bits de
poids faible de shmflg et tente de créer un nouveau
segment.
Les limites suivantes influent sur l'appel système
shmget :
- SHMALL
- Limite système du nombre de pages de mémoire
partagée, mesurée en unités de taille de page du
système.
- Sous Linux, cette limite peut être lue et modifiée
grâce au fichier /proc/sys/kernel/shmall. Depuis
Linux 3.16, la valeur par défaut de cette limite
est :
-
ULONG_MAX - 2^24
- L'effet de cette valeur (qui convient aux systèmes 32 et 64 bits)
est de n'imposer aucune limite aux allocations. Cette valeur,
utilisée à la place de ULONG_MAX, a été
choisie par défaut pour empêcher les cas où les
applications historiques dépassaient simplement la limite sans
vérifier préalablement sa valeur actuelle. De telles
applications créeraient un débordement de tampon si la
limite était fixée à ULONG_MAX.
- Entre Linux 2.2 et Linux 3.15, la valeur par défaut
de cette limite était :
-
SHMMAX / PAGE_SIZE * (SHMMNI / 16)
- Si SHMMAX et SHMMNI n'ont pas été
modifiés, la multiplication du résultat de cette formule par
la taille de la page (pour obtenir une valeur en octets) conduirait
à une valeur de 8 Go comme limite de mémoire totale
utilisée par tous les segments de mémoire
partagée.
- SHMMAX
- Taille maximale en octets d'un segment de mémoire
partagée.
- Sous Linux, cette limite peut être lue et modifiée
grâce au fichier /proc/sys/kernel/shmmax. Depuis
Linux 3.16, la valeur par défaut de cette limite
est :
-
ULONG_MAX - 2^24
- L'effet de cette valeur (qui s'applique aux systèmes 32 et 64 bits)
est de n'imposer aucune limite d'allocation. Consultez la description de
SHMALL sur un point sur la raison pour laquelle cette valeur par
défaut est utilisée (au lieu de ULONG_MAX).
- Entre Linux 2.2 et Linux 3.15, cette limite vaut par
défaut 0x2000000 (32 Mio).
- Comme il n'est pas possible de projeter une partie d'un segment de
mémoire partagé, la quantité de mémoire
virtuelle pose une autre limite à la taille maximum
d'élévation d'un segment utilisable : par exemple,
sur i389, les plus grands segments qui peuvent être projetés
ont une taille d'environ 2.8 Go, contre environ 127 To sur
un x89-64.
- SHMMIN
- Taille minimale, en octets, d'un segment partagé :
dépend de l'implémentation (actuellement 1 octet,
bien que PAGE_SIZE soit la valeur effectivement
utilisée).
- SHMMNI
- Limite système du nombre de segments de mémoire
partagée. Avec Linux 2.2, cette limite valait 128 par
défaut. Depuis Linux 2.4, cette valeur par défaut
vaut 4096.
- Sous Linux, cette limite peut être lue et modifiée
grâce au fichier /proc/sys/kernel/shmmni).
L'implémentation n'a pas de limite spécifique pour
le nombre maximal de segments partagés par processus
(SHMSEG).
Jusqu'à Linux 2.3.30, Linux renvoyait l'erreur
EIDRM pour un shmget() sur un segment de mémoire
marqué pour destruction.
Le choix du nom IPC_PRIVATE est malheureux, IPC_NEW
aurait mieux décrit sa fonction.
memfd_create(2), shmat(2), shmctl(2),
shmdt(2), ftok(3), capabilities(7),
shm_overview(7), sysvipc(7)
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.