Provided by: manpages-fr-dev_4.19.0-7_all bug

NOM

       semop, semtimedop - Opérations sur les sémaphores System V

BIBLIOTHÈQUE

       Bibliothèque C standard (libc, -lc)

SYNOPSIS

       #include <sys/sem.h>

       int semop(int semid, struct sembuf *sops, size_t nsops);
       int semtimedop(int semid, struct sembuf *sops, size_t nsops,
                      const struct timespec *_Nullable timeout);

   Exigences    de    macros    de   test   de   fonctionnalités   pour   la   glibc   (consulter
   feature_test_macros(7)) :

       semtimedop():
           _GNU_SOURCE

DESCRIPTION

       Chaque sémaphore dans un ensemble de sémaphores System V  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;   /* PID du dernier processus modifiant
                                        la valeur du sémaphore */

       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 l'ordre et atomiquement.
       Les opérations sont toutes réalisées en même temps, et seulement si elles  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 soustrait la valeur sem_op à la valeur de mise  à
       jour  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). Sinon, semzcnt (le décompte de threads en attente jusqu'à  ce  que  cette
       valeur  de  sémaphore  devienne zéro) est incrémenté d'un et le thread 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  thread  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.

       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  ajoute  la  valeur  absolue de sem_op à la valeur de mise à jour de
       sémaphore (semadj) pour ce sémaphore. 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  (le  décompte de threads en attente jusqu'à ce que cette valeur de sémaphore soit
       incrémenté) est incrémenté de un et le thread 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 : l'opération est
          effectuée comme décrit ci-dessus.

       •  Le jeu de sémaphores est supprimé. L'appel système échoue et  errno  contient  le  code
          d'erreur EIDRM.

       •  Le  thread  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.

       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 de l'appelant. Enfin sem_otime est défini à l'heure
       actuelle.

   semtimedop()
       La fonction semtimedop() se comporte comme semop() sauf que dans le cas où le thread  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 (cet intervalle de sommeil
       sera  arrondi  à  la  granularité  de l'horloge système, et les délais d'ordonnancement du
       noyau font que cette valeur peut être légèrement dépassée). 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().

       Si  semtimedop()  est  interrompu  par un signal, causant l'échec de l'appel avec l'erreur
       EINTR, les valeurs contenues dans timeout restent inchangées.

VALEUR RENVOYÉE

       En cas de réussite, semop() et semtimedop() renvoient 0. En cas d'échec, ils  renvoient -1
       et errno contient le code d'erreur.

ERREURS

       E2BIG  l'argument  nsops est supérieur à SEMOPM, le nombre maximal d'opérations autorisées
              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 dans
              l'espace de noms utilisateur qui régit son espace de noms IPC.

       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 ; consultez 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 Linux 2.3.3.

STANDARDS

       POSIX.1-2001, POSIX.1-2008, SVr4.

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.

       Une  valeur  de  mise  à jour de sémaphore (semadj) est un entier propre à un processus et
       sémaphore, qui représente le compte négatif des opérations utilisant l'attribut  SEM_UNDO.
       Chaque  processus dispose d'une liste de valeurs semadj — une valeur pour chaque sémaphore
       où SEM_UNDO a été utilisé. Quand un processus se termine, chacune des  valeurs  semadj  de
       ses  sémaphores  est  ajoutée  au  sémaphore  correspondant,  annulant  ainsi  l'effet des
       opérations du processus sur le sémaphore (voir la section  BOGUES  ci-dessous).  Quand  la
       valeur  d'un  sémaphore  est  définie  directement  par  une  requête  SETVAL ou SETALL de
       semctl(2), la valeur semadj correspondante est effacée dans tous les  processus.  L'option
       CLONE_SYSVSEM  de  clone(2)  permet à plusieurs processus de partager une liste de semadj.
       Consultez clone(2) pour plus d'informations.

       Les valeurs semval, sempid, semzcnt et semnct pour un sémaphore  peuvent  être  retrouvées
       avec des appels semctl(2) spécifiques.

   Limites des sémaphores
       Les limites suivantes de ressources concernent l'appel système semop() :

       SEMOPM Nombre  maximal d'opérations pour un appel à semop. Avant Linux 3.19, la valeur par
              défaut pour cette limite était de 32. Depuis Linux 3.19, cette valeur  est  de 500.
              Sous  Linux,  cette  limite  peut  être  lue  et modifiée via le troisième champ du
              fichier /proc/sys/kernel/sem. Note : cette limite ne  devrait  pas  être  augmentée
              au-delà  de 1000 à cause du risque que semop() échoue en raison de la fragmentation
              de la mémoire du noyau pendant l'allocation de mémoire pour copier le tableau sops.

       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 structures 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. Cela 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 Linux 2.6.x (x <= 10) un  bogue  peut,  dans  certaines  circonstances,  empêcher  un
       thread,  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 Linux 2.6.11.

EXEMPLES

       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 sémaphore 0 */
           sops[0].sem_op = 0;         /* Attendre que la valeur soit égale à 0 */
           sops[0].sem_flg = 0;

           sops[1].sem_num = 0;        /* Agir sur le sémaphore 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);
           }

       Un autre exemple de l'usage de semop() peut être trouvé dans shmop(2).

VOIR AUSSI

       clone(2),    semctl(2),   semget(2),   sigaction(2),   capabilities(7),   sem_overview(7),
       sysvipc(7), time(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  ⟨https://www.gnu.org/licenses/gpl-3.0.html⟩  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⟩.