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.
Consultez
shmop(2).
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
<
[email protected]>, Thierry Vignaud
<
[email protected]>, François Micaux, Alain Portal
<
[email protected]>, Jean-Philippe Guérard
<
[email protected]>, Jean-Luc Coulon (f5ibh)
<
[email protected]>, Julien Cristau
<
[email protected]>, Thomas Huriaux <
[email protected]>,
Nicolas François <
[email protected]>, Florentin
Duneau <
[email protected]>, Simon Paillard
<
[email protected]>, Denis Barbier
<
[email protected]>, David Prévot <
[email protected]> et
Jean-Philippe MENGUAL <
[email protected]>
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 à
[email protected]