NOM
semop, semtimedop - Opérations sur les sémaphores
SYNOPSIS
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
int semop(int semid, struct sembuf *sops, unsigned nsops);
int semtimedop(int semid, struct sembuf *sops, unsigned nsops,
struct timespec *timeout);
Exigences de macros de test de fonctionnalités pour la glibc (voir
feature_test_macros(7)) :
semtimedop() : _GNU_SOURCE
Chaque sémaphore dans un ensemble de sémaphores se voit associer les
valeurs suivantes :
unsigned short semval; /* valeur du sémaphore */
unsigned short semzcnt; /* # Attente pour zéro */
unsigned short semncnt; /* # Attente d’incrément */
pid_t sempid; /* dernier processus agissant */
La fonction semop() effectue des opérations sur les membres de
l’ensemble de sémaphores identifié par semid. Chacun des nsops éléments
dans le tableau pointé par sops indique une opération à effectuer sur
un sémaphore en utilisant une structure struct sembuf contenant les
membres suivants :
unsigned short sem_num; /* Numéro du sémaphore */
short sem_op; /* Opération sur le sémaphore */
short sem_flg; /* Options pour l’opération */
Les options possibles pour sem_flg sont IPC_NOWAIT et SEM_UNDO. Si une
opération indique l’option SEM_UNDO, elle sera annulée lorsque le
processus se terminera.
L’ensemble des opérations contenues dans sops est effectué dans lordre
et atomiquement. Les opérations sont toutes réalisées en même temps, et
seulement si elle peuvent toutes être effectuées. Le comportement de
l’appel système si toutes les opérations ne sont pas réalisables dépend
de la présence de l’attribut IPC_NOWAIT dans les champs sem_flg décrits
plus bas.
Chaque opération est effectuée sur le sem_num-ième sémaphore de
l’ensemble. Le premier sémaphore est le numéro 0. Pour chaque
sémaphore, l’opération est l’une des trois décrites ci-dessous.
Si l’argument sem_op est un entier positif, la fonction ajoute cette
valeur à semval. De plus si SEM_UNDO est demandé, le système met à jour
le compteur « undo » du sémaphore (semadj). Cette opération n’est
jamais bloquante. Le processus appelant doit avoir l’autorisation de
modification sur le jeu de sémaphores.
Si sem_op vaut zéro le processus doit avoir l’autorisation de lecture
sur l’ensemble de sémaphores. Le processus attend que semval soit nul :
si semval vaut zéro, l’appel système continue immédiatement. Sinon, si
l’on a réclamé IPC_NOWAIT dans sem_flg, l’appel système semop() échoue
et errno contient le code d’erreur EAGAIN (et aucune des opérations de
sops n’est réalisée). Autrement semzcnt est incrémenté de 1 et le
processus s’endort jusqu’à ce que l’un des événements suivants se
produise:
· semval devient égal à 0, alors semzcnt est décrémenté.
· Le jeu de sémaphores est supprimé. L’appel système échoue et errno
contient le code d’erreur EIDRM.
· Le processus reçoit un signal à intercepter, la valeur de semzcnt
est décrémentée et l’appel système échoue avec errno contenant le
code d’erreur EINTR.
· La limite temporelle indiqué par timeout dans un semtimedop() a
expiré : l’appel système échoue avec errno contenant EAGAIN.
Si sem_op est inférieur à zéro, le processus appelant doit avoir
l’autorisation de modification sur le jeu de sémaphores. Si semval est
supérieur ou égal à la valeur absolue de sem_op, la valeur absolue de
sem_op est soustraite de semval, et si SEM_UNDO est indiqué, le système
met à jour le compteur « undo » du sémaphore (semadj). Puis l’appel
système continue. Si la valeur absolue de sem_op est plus grande que
semval, et si l’on a réclamé IPC_NOWAIT dans sem_flg, l’appel système
échoue et errno contient le code d’erreur EAGAIN (et aucune des
opérations de sops n’est réalisée). Sinon semncnt est incrémenté de un
et le processus s’endort jusqu’à ce que l’un des événements suivants se
produise :
· semval devient supérieur ou égal à la valeur absolue de sem_op,
alors la valeur semncnt est décrémentée, la valeur absolue de sem_op
est soustraite de semval et si SEM_UNDO est demandé le système met à
jour le compteur « undo » (semadj) du sémaphore.
· Le jeu de sémaphores est supprimé. L’appel système échoue et errno
contient le code d’erreur EIDRM.
· Le processus reçoit un signal à intercepter, la valeur de semncnt
est décrémentée et l’appel système échoue avec errno contenant le
code d’erreur EINTR.
· La limite temporelle indiqué par timeout dans un semtimedop() a
expiré : l’appel système échoue avec errno contenant EAGAIN.
En cas de succès, le membre sempid de chacun des sémaphores indiqués
dans le tableau pointé par sops est rempli avec le PID du processus
appelant. Enfin sem_otime est fixé à l’heure actuelle.
La fonction semtimedop() se comporte comme semop() sauf que dans le cas
où le processus doit dormir, la durée maximale du sommeil est limitée
par la valeur spécifiée dans la structure timespec dont l’adresse est
transmise dans le paramètre timeout. Si la limite indiquée a été
atteinte, l’appel système échoue avec errno contenant EAGAIN (et aucune
opération de sops n’est réalisée). Si le paramètre timeout est NULL,
alors semtimedop() se comporte exactement comme semop().
VALEUR RENVOYÉE
En cas de réussite, semop() et semtimedop() renvoient 0. Sinon ils
renvoient -1 et errno contient le code d’erreur.
ERREURS
En cas d’erreur, errno prend l’une des valeurs suivantes :
E2BIG l’argument nsops est supérieur à SEMOPM, le nombre maximal
d’opérations par appel système.
EACCES Le processus appelant n’a pas les permissions nécessaires pour
effectuer les opérations sur les sémaphores spécifiés et n’a pas
la capacité CAP_IPC_OWNER.
EAGAIN Une opération ne pouvait pas être effectuée immédiatement et
IPC_NOWAIT a été indiqué dans l’argument sem_flg, ou la durée
limite indiquée dans timeout a expiré.
EFAULT sops ou timeout pointent en dehors de l’espace d’adressage
accessible.
EFBIG La valeur de sem_num est inférieure à 0 ou supérieure ou égale
au nombre de sémaphores dans l’ensemble.
EIDRM Le jeu de sémaphores a été supprimé.
EINTR Un signal a été reçu pendant l’attente ; voir signal(7).
EINVAL L’ensemble de sémaphores n’existe pas ou semid est inférieur à
zéro, ou nsops n’est pas strictement positive.
ENOMEM L’argument sem_flg de certaines opérations demande SEM_UNDO et
le système n’a pas assez de mémoire pour allouer les structures
nécessaires.
ERANGE sem_op+semval est supérieur à SEMVMX (la valeur maximale de
semval autorisée par l’implémentation) pour l’une des
opérations.
VERSIONS
semtimedop() est apparu pour la première fois dans Linux 2.5.52, puis a
été rétroporté au noyau 2.4.22. La gestion de semtimedop() dans la
glibc date de la version 2.3.3.
CONFORMITÉ
SVr4, POSIX.1-2001.
NOTES
Les structures sem_undo d’un processus ne sont pas héritées par ses
enfants lors d’un fork(2), mais elles le sont lors d’un appel système
execve(2).
semop() n’est jamais relancé automatiquement après avoir été interrompu
par un gestionnaire de signal quelque soit l’attribut SA_RESTART durant
l’installation du gestionnaire.
semadj est un entier pour le processus qui représente simplement le
compte (négatif) des opérations sur le sémaphore réalisées par
l’attribut SEM_UNDO. Quand la valeur d’un sémaphore est fixée
directement par une requête SETVAL ou SETALL de semctl(2), la valeur
semadj correspondante est effacée dans tous les processus.
Les valeurs semval, sempid, semzcnt, et semnct pour un sémaphore
peuvent être retrouvées avec des appels semctl(2) spécifiques.
Les limites système suivantes concernent semop() :
SEMOPM Nombre maximal d’opérations pour une appel à semop() (32). Sous
Linux, cette limite peut être lue et modifiée via le troisième
champ du fichier /proc/sys/kernel/sem.
SEMVMX Valeur maximale pour semval : dépendante de l’implémentation
(32767).
L’implémentation n’a pas de limites intrinsèques pour la valeur
maximale d’effacement en sortie (SEMAEM), le nombre de structure
d’annulation sur le système (SEMMNU), et le nombre maximal de
structures d’annulation pour un processus.
BOGUES
Quand un processus se termine, l’ensemble des structures semadj qui lui
sont associées servent à annuler les effets de toutes les opérations
sur les sémaphores réalisées avec l’attribut SEM_UNDO. Ceci pose un
problème : si l’une (ou plusieurs) des modifications sur les sémaphores
demande une descente du compteur d’un sémaphore au-dessous de zéro, que
doit faire l’implémentation ? Une approche possible consiste à bloquer
jusqu’à ce que la modification du sémaphore soit possible. C’est
néanmoins peu désirable car la terminaison du processus peut alors
bloquer pendant une période arbitrairement longue. Une autre
possibilité est d’ignorer la modification du sémaphore (comme un échec
lorsque IPC_NOWAIT est spécifié durant une opération). Linux adopte une
troisième approche : décroître la valeur du sémaphore autant que
possible (jusqu’à zéro) et permettre au processus de se terminer
immédiatement.
Dans les noyaux 2.6.x (x <= 10) un bogue peut, dans certaines
circonstances, empêcher un processus attendant que la valeur d’un
sémaphore s’annule d’être réveillé quand cette valeur atteint 0. Ce
bogue est corrigé dans le noyau 2.6.11.
EXEMPLE
Le bout de code suivant utilise semop() pour attendre de façon atomique
que la valeur du sémaphore 0 vaille zéro, puis incrémente la valeur du
sémaphore de un.
struct sembuf sops[2];
int semid;
/* Le code pour configurer semid est omis */
sops[0].sem_num = 0; /* Agir sur le semaphore 0 */
sops[0].sem_op = 0; /* Attendre que la valeur soit égal à 0 */
sops[0].sem_flg = 0;
sops[1].sem_num = 0; /* Agir sur le semaphore 0 */
sops[1].sem_op = 1; /* Incrémenter la valeur de un */
sops[1].sem_flg = 0;
if (semop(semid, sops, 2) == -1) {
perror("semop");
exit(EXIT_FAILURE);
}
VOIR AUSSI
semctl(2), semget(2), sigaction(2), capabilities(7), sem_overview(7),
svipc(7), time(7)
COLOPHON
Cette page fait partie de la publication 3.23 du projet man-pages
Linux. Une description du projet et des instructions pour signaler des
anomalies peuvent être trouvées à l’adresse
http://www.kernel.org/doc/man-pages/.
TRADUCTION
Cette page de manuel a été traduite et mise à jour par Christophe
Blaess <http://www.blaess.fr/christophe/> entre 1996 et 2003, puis par
Alain Portal <aportal AT univ-montp2 DOT fr> jusqu’en 2006, et mise à
disposition sur http://manpagesfr.free.fr/.
Les mises à jour et corrections de la version présente dans Debian sont
directement gérées par Julien Cristau <jcristau@debian.org> et l’équipe
francophone de traduction de Debian.
Veuillez signaler toute erreur de traduction en écrivant à
<debian-l10n-french@lists.debian.org> ou par un rapport de bogue sur le
paquet manpages-fr.
Vous pouvez toujours avoir accès à la version anglaise de ce document
en utilisant la commande « man -L C <section> <page_de_man> ».