semget
Section: System Calls (2)
Updated: 5 février 2023
Index
Return to Main Contents
NOM
semget - Obtenir l'identifiant d'un ensemble de sémaphores System V
BIBLIOTHÈQUE
Bibliothèque C standard (libc, -lc)
SYNOPSIS
#include <sys/sem.h>
int semget(key_t key, int nsems, int semflg);
DESCRIPTION
L'appel système semget() renvoie l'identifiant de l'ensemble de
sémaphores System V associé à la valeur de clé key. Cela peut servir pour
obtenir l'identifiant d'un ensemble de sémaphores créé précédemment (lorsque
semflg vaut 0 et que key n'a pas la valeur IPC_PRIVATE) ou pour
créer un nouvel ensemble.
Un nouvel ensemble contenant nsems sémaphores est créé si key a la
valeur IPC_PRIVATE ou si aucun ensemble n'est associé à key, et si
l'option IPC_CREAT est présente dans semflg.
Si semflg contient à la fois IPC_CREAT et IPC_EXCL et qu'un
ensemble de sémaphores existe déjà pour la clé key, semget() échoue et
errno vaut EEXIST. (Cela est analogue à l'effet de la combinaison
O_CREAT | O_EXCL pour open(2).)
Pendant la création, les 9 bits de poids faible de l'argument semflg
définissent les permissions d'accès (pour le propriétaire, le groupe et les
autres) au jeu de sémaphores, en utilisant le même format et la même
signification que les droits d'accès dans open(2). Les permissions
d'exécution ne sont pas utilisées par le système, et pour un jeu de
sémaphores, l'autorisation d'écriture signifie autorisation de modification.
Durant la création, la structure de données semid_ds (consultez
semctl(2)) contrôlant le jeu de sémaphores est initialisée ainsi par
semget() :
- •
-
sem_perm.cuid et sem_perm.uid contiennent l'UID effectif du processus
appelant.
- •
-
sem_perm.cgid et sem_perm.gid contiennent le GID effectif du processus
appelant.
- •
-
Les 9 bits de poids faible de sem_perm.mode contiennent les 9 bits de
poids faible de semflg.
- •
-
sem_nsems reçoit la valeur nsems.
- •
-
sem_otime est mis à 0.
- •
-
sem_ctime est rempli avec l'heure actuelle.
L'argument nsems peut valoir 0 (ignoré) si l'appel système n'est pas une
création d'ensemble de sémaphores. Autrement nsems doit être supérieur
à 0 et inférieur ou égal au nombre maximal de sémaphores par ensemble
(SEMMSL).
Si le jeu de sémaphores existe déjà, les permissions d'accès sont
contrôlées.
VALEUR RENVOYÉE
En cas de réussite, semget() renvoie l'identifiant de l'ensemble de
sémaphores (un entier positif). En cas d'échec, il renvoie -1 et errno
contient le code d'erreur.
ERREURS
- EACCES
-
Le jeu de sémaphores associé à key existe, mais le processus n'a aucun
droit d'accès sur lui et n'a pas la capacité CAP_IPC_OWNER dans l'espace
de noms utilisateur qui régit son espace de noms IPC.
- EEXIST
-
IPC_CREAT et IPC_EXCL ont été tous les deux indiqués dans semflag,
mais un ensemble de sémaphores de clé key existe déjà.
- EINVAL
-
nsems est inférieur à zéro ou supérieur à la limite du nombre de
sémaphores par ensemble, (SEMMSL).
- EINVAL
-
Un ensemble de sémaphores identifié par key existe déjà, mais nsems
est plus grand que le nombre de sémaphores par ensemble.
- ENOENT
-
Aucun jeu de sémaphores associé a key n'existe et l'argument semflg ne
précise pas IPC_CREAT.
- ENOMEM
-
Pas assez de mémoire pour créer les structures nécessaires.
- ENOSPC
-
Le nombre maximal de jeux de sémaphores sur le système (SEMMNI) est
atteint, ou le nombre maximal de sémaphores sur le système est atteint
(SEMMNS).
STANDARDS
SVr4, POSIX.1-2001.
NOTES
IPC_PRIVATE n'est pas une option, mais un objet de type key_t. Si l'on
utilise cette valeur spéciale dans l'argument key, l'appel système ne se
préoccupera que des 9 bits de poids faible de semflg et tentera de créer
un nouveau jeu de sémaphores.
Initialisation des sémaphores
Les valeurs des sémaphores dans un ensemble qui vient d'être créé sont
indéterminées (POSIX.1-2001 et POSIX.1-2008 sont explicites sur ce point,
bien que POSIX.1-2008 note que de futures versions du standard pourraient
exiger des implémentations qu'elles initialisent les sémaphores à 0). Même
si Linux, comme de nombreuses autres implémentations, initialise les valeurs
des sémaphores à 0, une application portable ne peut pas compter sur cette
initialisation : elle doit initialiser explicitement les sémaphores à la
valeur souhaitée.
L'initialisation peut être effectuée avec les opérations SETVAL ou
SETALL de la fonction semctl(2). Lorsque plusieurs concurrents ne
savent pas qui sera le premier à initialiser le jeu de sémaphores, il est
possible de vérifier que le membre sem_otime de la structure récupérée
par une opération IPC_STAT de semctl(2) est non nul pour éviter les
conditions de concurrence.
Limites des sémaphores
Les limites suivantes de ressources concernent l'appel système semget() :
- SEMMNI
-
Limite système du nombre de jeux de sémaphores. Avant Linux 3.19, la valeur
par défaut pour cette limite était de 128. Depuis Linux 3.19, elle est de
32 000. Sous Linux, cette limite peut être lue et modifiée dans le quatrième
champ de /proc/sys/kernel/sem.
- SEMMSL
-
Nombre maximal de sémaphores par ensemble. Avant Linux 3.19, la valeur par
défaut pour cette limite était de 250. Depuis Linux 3.19, elle est de
32 000. Sous Linux, cette limite peut être lue et modifiée dans le premier
champ de /proc/sys/kernel/sem.
- SEMMNS
-
Limite système du nombre de sémaphores : dépend de la politique (sous Linux,
cette limite peut être lue et modifiée dans le second champ de
/proc/sys/kernel/sem). Le nombre de sémaphores est également limité par
le produit de SEMMSL et SEMMNI.
BOGUES
Le choix du nom IPC_PRIVATE est malheureux, IPC_NEW aurait mieux
décrit sa fonction.
EXEMPLES
Le programme montré ci-dessous utilise semget() pour créer un nouveau jeu
de sémaphores ou récupère l'identifiant d'un jeu existant. Il génère la
key pour semget() en utilisant ftok(3). Les deux premiers arguments
de la ligne de commande sont utilisés comme arguments de chemin pathname
et proj_id pour ftok(3). Le troisième argument de la ligne de commande
est un entier qui spécifie l'argument nsems pour semget(). Les options
en ligne de commande peuvent être utilisées pour spécifier les attributs
IPC_CREAT (-c) et IPC_EXCL (-x) pour l'appel à
semget(). L'utilisation de ce programme est expliquée ci-dessous.
Sont créés en premier deux fichiers qui seront utilisés pour générer les
clés avec ftok(3), puis deux jeux de sémaphores utilisant ces fichiers et
enfin, les jeux sont listés avec ipcs(1):
$ touch mykey mykey2
$ ./t_semget -c mykey p 1
ID = 9
$ ./t_semget -c mykey2 p 2
ID = 10
$ ipcs -s
------ Semaphore Arrays --------
key semid owner perms nsems
0x7004136d 9 mtk 600 1
0x70041368 10 mtk 600 2
Ensuite, il est démontré que quand semctl(2) reçoit la même key
(puisque générée par les mêmes arguments passés à ftok(3)), il renvoie
l'identifiant du jeu de sémaphore déjà existant :
$ ./t_semget -c mykey p 1
ID = 9
Finalement, il est montré quel type de collision peut survenir si ftok(3)
reçoit des arguments de chemin pathname différents qui possèdent le même
numéro d'inode :
$ ln mykey link
$ ls -i1 link mykey
2233197 link
2233197 mykey
$ ./t_semget link p 1 # Génère la même clé que 'mykey'
ID = 9
Source du programme
/* t_semget.c
Licensed under GNU General Public License v2 or later.
*/
#include <stdio.h>
#include <stdlib.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <unistd.h>
static void
usage(const char *pname)
{
fprintf(stderr, "Usage: %s [-cx] pathname proj-id num-sems\n",
pname);
fprintf(stderr, " -c Use IPC_CREAT flag\n");
fprintf(stderr, " -x Use IPC_EXCL flag\n");
exit(EXIT_FAILURE);
}
int
main(int argc, char *argv[])
{
int semid, nsems, flags, opt;
key_t key;
flags = 0;
while ((opt = getopt(argc, argv, "cx")) != -1) {
switch (opt) {
case ':c': flags |= IPC_CREAT; break;
case ':x': flags |= IPC_EXCL; break;
default: usage(argv[0]);
}
}
if (argc != optind + 3)
usage(argv[0]);
key = ftok(argv[optind], argv[optind + 1][0]);
if (key == -1) {
perror("ftok");
exit(EXIT_FAILURE);
nsems = atoi(argv[optind + 2]);
semid = semget(key, nsems, flags | 0600);
if (semid == -1) {
perror("semget");
exit(EXIT_FAILURE);
}
printf("ID = %d\n", semid);
exit(EXIT_SUCCESS);
}
VOIR AUSSI
semctl(2), semop(2), ftok(3), capabilities(7),
sem_overview(7), sysvipc(7)
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>,
Thomas Vincent <tvincent@debian.org>
et
Jean-Pierre Giraud <jean-pierregiraud@neuf.fr>
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 à
Index
- NOM
-
- BIBLIOTHÈQUE
-
- SYNOPSIS
-
- DESCRIPTION
-
- VALEUR RENVOYÉE
-
- ERREURS
-
- STANDARDS
-
- NOTES
-
- Initialisation des sémaphores
-
- Limites des sémaphores
-
- BOGUES
-
- EXEMPLES
-
- Source du programme
-
- VOIR AUSSI
-
- TRADUCTION
-
This document was created by
man2html,
using the manual pages.
Time: 06:49:02 GMT, May 18, 2024