Loading

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> ».