semop(2) System Calls Manual semop(2) NOM semop, semtimedop - Operations sur les semaphores System V BIBLIOTHEQUE Bibliotheque C standard (libc, -lc) SYNOPSIS #include 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 fonctionnalites pour la glibc (consulter feature_test_macros(7)) : semtimedop(): _GNU_SOURCE DESCRIPTION Chaque semaphore dans un ensemble de semaphores System V se voit associer les valeurs suivantes : unsigned short semval; /* Valeur du semaphore */ unsigned short semzcnt; /* # Attente pour zero */ unsigned short semncnt; /* # Attente d'increment */ pid_t sempid; /* PID du dernier processus modifiant la valeur du semaphore */ La fonction semop() effectue des operations sur les membres de l'ensemble de semaphores identifie par semid. Chacun des nsops elements dans le tableau pointe par sops indique une operation a effectuer sur un semaphore en utilisant une structure struct sembuf contenant les membres suivants : unsigned short sem_num; /* Numero du semaphore */ short sem_op; /* Operation sur le semaphore */ short sem_flg; /* Options pour l'operation */ Les options possibles pour sem_flg sont IPC_NOWAIT et SEM_UNDO. Si une operation indique l'option SEM_UNDO, elle sera annulee lorsque le processus se terminera. L'ensemble des operations contenues dans sops est effectue dans l'ordre et atomiquement. Les operations sont toutes realisees en meme temps, et seulement si elles peuvent toutes etre effectuees. Le comportement de l'appel systeme, si toutes les operations ne sont pas realisables, depend de la presence de l'attribut IPC_NOWAIT dans les champs sem_flg decrits plus bas. Chaque operation est effectuee sur le sem_num-ieme semaphore de l'ensemble. Le premier semaphore est le numero 0. Pour chaque semaphore, l'operation est l'une des trois decrites ci-dessous. Si l'argument sem_op est un entier positif, la fonction ajoute cette valeur a semval. De plus si SEM_UNDO est demande, le systeme soustrait la valeur sem_op a la valeur de mise a jour du semaphore (semadj). Cette operation n'est jamais bloquante. Le processus appelant doit avoir l'autorisation de modification sur le jeu de semaphores. Si sem_op vaut zero le processus doit avoir l'autorisation de lecture sur l'ensemble de semaphores. Le processus attend que semval soit nul : si semval vaut zero, l'appel systeme continue immediatement. Sinon, si l'on a reclame IPC_NOWAIT dans sem_flg, l'appel systeme semop() echoue et errno contient le code d'erreur EAGAIN (et aucune des operations de sops n'est realisee). Sinon, semzcnt (le decompte de threads en attente jusqu'a ce que cette valeur de semaphore devienne zero) est incremente d'un et le thread s'endort jusqu'a ce que l'un des evenements suivants se produise : - semval devient egal a 0, alors semzcnt est decremente. - Le jeu de semaphores est supprime. L'appel systeme echoue et errno contient le code d'erreur EIDRM. - Le thread recoit un signal a intercepter, la valeur de semzcnt est decrementee et l'appel systeme echoue avec errno contenant le code d'erreur EINTR. Si sem_op est inferieur a zero, le processus appelant doit avoir l'autorisation de modification sur le jeu de semaphores. Si semval est superieur ou egal a la valeur absolue de sem_op, la valeur absolue de sem_op est soustraite de semval, et si SEM_UNDO est indique, le systeme ajoute la valeur absolue de sem_op a la valeur de mise a jour de semaphore (semadj) pour ce semaphore. Si la valeur absolue de sem_op est plus grande que semval et si l'on a reclame IPC_NOWAIT dans sem_flg, l'appel systeme echoue et errno contient le code d'erreur EAGAIN (et aucune des operations de sops n'est realisee). Sinon, semncnt (le decompte de threads en attente jusqu'a ce que cette valeur de semaphore soit incremente) est incremente de un et le thread s'endort jusqu'a ce que l'un des evenements suivants se produise : - semval devient superieur ou egal a la valeur absolue de sem_op : l'operation est effectuee comme decrit ci-dessus. - Le jeu de semaphores est supprime. L'appel systeme echoue et errno contient le code d'erreur EIDRM. - Le thread recoit un signal a intercepter, la valeur de semncnt est decrementee et l'appel systeme echoue avec errno contenant le code d'erreur EINTR. En cas de succes, le membre sempid de chacun des semaphores indiques dans le tableau pointe par sops est rempli avec le PID de l'appelant. Enfin sem_otime est defini a l'heure actuelle. semtimedop() La fonction semtimedop() se comporte comme semop() sauf que dans le cas ou le thread doit dormir, la duree maximale du sommeil est limitee par la valeur specifiee dans la structure timespec dont l'adresse est transmise dans le parametre timeout (cet intervalle de sommeil sera arrondi a la granularite de l'horloge systeme, et les delais d'ordonnancement du noyau font que cette valeur peut etre legerement depassee). Si la limite indiquee a ete atteinte, l'appel systeme echoue avec errno contenant EAGAIN (et aucune operation de sops n'est realisee). Si le parametre timeout est NULL, alors semtimedop() se comporte exactement comme semop(). Si semtimedop() est interrompu par un signal, causant l'echec de l'appel avec l'erreur EINTR, les valeurs contenues dans timeout restent inchangees. VALEUR RENVOYEE En cas de reussite, semop() et semtimedop() renvoient 0. En cas d'echec, ils renvoient -1 et errno contient le code d'erreur. ERREURS E2BIG l'argument nsops est superieur a SEMOPM, le nombre maximal d'operations autorisees par appel systeme. EACCES Le processus appelant n'a pas les permissions necessaires pour effectuer les operations sur les semaphores specifies et n'a pas la capacite CAP_IPC_OWNER dans l'espace de noms utilisateur qui regit son espace de noms IPC. EAGAIN Une operation ne pouvait pas etre effectuee immediatement et IPC_NOWAIT a ete indique dans l'argument sem_flg, ou la duree limite indiquee dans timeout a expire. EFAULT sops ou timeout pointent en dehors de l'espace d'adressage accessible. EFBIG La valeur de sem_num est inferieure a 0 ou superieure ou egale au nombre de semaphores dans l'ensemble. EIDRM Le jeu de semaphores a ete supprime. EINTR Un signal a ete recu pendant l'attente ; consultez signal(7). EINVAL L'ensemble de semaphores n'existe pas ou semid est inferieur a zero, ou nsops n'est pas strictement positive. ENOMEM L'argument sem_flg de certaines operations demande SEM_UNDO et le systeme n'a pas assez de memoire pour allouer les structures necessaires. ERANGE sem_op+semval est superieur a SEMVMX (la valeur maximale de semval autorisee par l'implementation) pour l'une des operations. STANDARDS POSIX.1-2008. VERSIONS Linux 2.5.52 (retroportage dans Linux 2.4.22), glibc 2.3.3. POSIX.1-2001, SVr4. NOTES Les structures sem_undo d'un processus ne sont pas heritees par ses enfants lors d'un fork(2), mais elles le sont lors d'un appel systeme execve(2). semop() n'est jamais relance automatiquement apres avoir ete interrompu par un gestionnaire de signal quelque soit l'attribut SA_RESTART durant l'installation du gestionnaire. Une valeur de mise a jour de semaphore (semadj) est un entier propre a un processus et semaphore, qui represente le compte negatif des operations utilisant l'attribut SEM_UNDO. Chaque processus dispose d'une liste de valeurs semadj -- une valeur pour chaque semaphore ou SEM_UNDO a ete utilise. Quand un processus se termine, chacune des valeurs semadj de ses semaphores est ajoutee au semaphore correspondant, annulant ainsi l'effet des operations du processus sur le semaphore (voir la section BOGUES ci-dessous). Quand la valeur d'un semaphore est definie directement par une requete SETVAL ou SETALL de semctl(2), la valeur semadj correspondante est effacee dans tous les processus. L'option CLONE_SYSVSEM de clone(2) permet a plusieurs processus de partager une liste de semadj. Consultez clone(2) pour plus d'informations. Les valeurs semval, sempid, semzcnt et semnct pour un semaphore peuvent etre retrouvees avec des appels semctl(2) specifiques. Limites des semaphores Les limites suivantes de ressources concernent l'appel systeme semop() : SEMOPM Nombre maximal d'operations pour un appel a semop. Avant Linux 3.19, la valeur par defaut pour cette limite etait de 32. Depuis Linux 3.19, cette valeur est de 500. Sous Linux, cette limite peut etre lue et modifiee via le troisieme champ du fichier /proc/sys/kernel/sem. Note : cette limite ne devrait pas etre augmentee au-dela de 1000 a cause du risque que semop() echoue en raison de la fragmentation de la memoire du noyau pendant l'allocation de memoire pour copier le tableau sops. SEMVMX Valeur maximale pour semval : dependante de l'implementation (32767). L'implementation n'a pas de limites intrinseques pour la valeur maximale d'effacement en sortie (SEMAEM), le nombre de structures d'annulation sur le systeme (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 associees servent a annuler les effets de toutes les operations sur les semaphores realisees avec l'attribut SEM_UNDO. Cela pose un probleme : si l'une (ou plusieurs) des modifications sur les semaphores demande une descente du compteur d'un semaphore au-dessous de zero, que doit faire l'implementation ? Une approche possible consiste a bloquer jusqu'a ce que la modification du semaphore soit possible. C'est neanmoins peu desirable, car la terminaison du processus peut alors bloquer pendant une periode arbitrairement longue. Une autre possibilite est d'ignorer la modification du semaphore (comme un echec lorsque IPC_NOWAIT est specifie durant une operation). Linux adopte une troisieme approche : decroitre la valeur du semaphore autant que possible (jusqu'a zero) et permettre au processus de se terminer immediatement. Dans Linux 2.6.x (x <= 10) un bogue peut, dans certaines circonstances, empecher un thread, attendant que la valeur d'un semaphore s'annule, d'etre reveille quand cette valeur atteint 0. Ce bogue est corrige dans le Linux 2.6.11. EXEMPLES Le bout de code suivant utilise semop() pour attendre de facon atomique que la valeur du semaphore 0 vaille zero, puis incremente la valeur du semaphore 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 egale a 0 */ sops[0].sem_flg = 0; sops[1].sem_num = 0; /* Agir sur le semaphore 0 */ sops[1].sem_op = 1; /* Incrementer 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 etre trouve 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 francaise de cette page de manuel a ete creee par Christophe Blaess , Stephan Rafin , Thierry Vignaud , Francois Micaux, Alain Portal , Jean-Philippe Guerard , Jean-Luc Coulon (f5ibh) , Julien Cristau , Thomas Huriaux , Nicolas Francois , Florentin Duneau , Simon Paillard , Denis Barbier , David Prevot , Thomas Vincent et Jean- Pierre Giraud Cette traduction est une documentation libre ; veuillez vous reporter a la GNU General Public License version 3 concernant les conditions de copie et de distribution. Il n'y a aucune RESPONSABILITE LEGALE. Si vous decouvrez un bogue dans la traduction de cette page de manuel, veuillez envoyer un message a . Pages du manuel de Linux 6.06 31 octobre 2023 semop(2)