Provided by:
manpages-fr-dev_3.27fr1.4-1_all 
NOM
sem_wait, sem_timedwait, sem_trywait - Verrouiller un semaphore
SYNOPSIS
#include <semaphore.h>
int sem_wait(sem_t *sem);
int sem_trywait(sem_t *sem);
int sem_timedwait(sem_t *sem, const struct timespec *abs_timeout);
Effectuez l'edition des liens avec l'option -lrt ou -pthread.
Exigences de macros de test de fonctionnalites pour la glibc (consultez
feature_test_macros(7)) :
sem_timedwait() : _POSIX_C_SOURCE >= 200112L || _XOPEN_SOURCE >= 600
DESCRIPTION
sem_wait() decremente (verrouille) le semaphore pointe par sem. Si la
valeur du semaphore est plus grande que 0, la decrementation s'effectue
et la fonction revient immediatement. Si le semaphore vaut zero,
l'appel bloquera jusqu'a ce que soit il devienne disponible d'effectuer
la decrementation (c'est-a-dire la valeur du semaphore n'est plus
nulle), soit un gestionnaire de signaux interrompe l'appel.
sem_trywait() est pareil que sem_wait(), excepte que si la
decrementation ne peut pas etre effectuee immediatement, l'appel
renvoie une erreur (errno vaut EAGAIN) plutot que bloquer.
sem_timedwait() est pareil que sem_wait(), excepte que abs_timeout
specifie une limite sur le temps pendant lequel l'appel bloquera si la
decrementation ne peut pas etre effectuee immediatement. L'argument
abs_timeout pointe sur une structure qui specifie un temps absolu en
secondes et nanosecondes depuis l'epoque, 1er janvier 1970 a 00:00:00
(UTC). Cette structure est definie de la maniere suivante :
struct timespec {
time_t tv_sec; /* Secondes */
long tv_nsec; /* Nanosecondes [0 .. 999999999] */
};
Si le delai est deja expire a l'heure de l'appel et si le semaphore ne
peut pas etre verrouille immediatement, sem_timedwait() echoue avec
l'erreur d'expiration de delai (errno vaut ETIMEDOUT).
Si l'operation peut etre effectuee immediatement, sem_timedwait()
n'echoue jamais avec une valeur d'expiration de delai, quelque soit la
valeur de abs_timeout. De plus, la validite de abs_timeout n'est pas
verifiee dans ce cas.
VALEUR RENVOY'EE
Toutes ces fonctions renvoient 0 si elles reussissent. Si elles
echouent, la valeur du semaphore n'est pas modifiee, elles renvoient -1
et ecrivent errno en consequence.
ERREURS
EINTR L'appel a ete interrompu par un gestionnaire de signal ;
consultez signal(7).
EINVAL sem n'est pas un semaphore valide.
L'erreur supplementaire suivante peut survenir pour sem_trywait() :
EAGAIN L'operation ne peut pas etre effectuee sans bloquer
(c'est-a-dire, le semaphore a une valeur nulle).
Les erreurs supplementaires suivantes peuvent survenir pour
sem_timedwait() :
EINVAL La valeur de abs_timeout.tv_nsecs est plus petite que 0 ou
superieure ou egale a 1 milliard.
ETIMEDOUT
Le delai a expire avant que le semaphore ait pu etre verrouille.
CONFORMIT'E
POSIX.1-2001.
NOTES
Un gestionnaire de signaux interrompra toujours un appel bloque a l'une
de ces fonctions, quelque soit l'utilisation de l'attribut SA_RESTART
de sigaction(2).
EXEMPLE
Le (quelque peu trivial) programme suivant opere sur un semaphore non
nomme. Il attend deux arguments sur la ligne de commande. Le premier
argument specifie une valeur en secondes qui est utilisee pour
configurer une alarme pour generer un signal SIGALRM. Ce gestionnaire
effectue un sem_post(3) pour incrementer le semaphore qui est attendu
dans le main() en utilisant sem_timedwait(). Le second argument de la
ligne de commande specifie la duree, en secondes, du delai d'attente
pour sem_timedwait(). Ci-dessous, le resultat de deux executions
differentes du programme :
$ ./a.out 2 3
About to call sem_timedwait()
sem_post() from handler
sem_getvalue() from handler; value = 1
sem_timedwait() succeeded
$ ./a.out 2 1
About to call sem_timedwait()
sem_timedwait() timed out
Source du programme
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <semaphore.h>
#include <time.h>
#include <assert.h>
#include <errno.h>
#include <signal.h>
sem_t sem;
#define handle_error(msg) \
do { perror(msg); exit(EXIT_FAILURE); } while (0)
static void
handler(int sig)
{
write(STDOUT_FILENO, "sem_post() from handler\n", 24);
if (sem_post(&sem) == -1) {
write(STDERR_FILENO, "sem_post() failed\n", 18);
_exit(EXIT_FAILURE);
}
}
int
main(int argc, char *argv[])
{
struct sigaction sa;
struct timespec ts;
int s;
if (argc != 3) {
fprintf(stderr, "Usage: %s <alarm-secs> <wait-secs>\n",
argv[0]);
exit(EXIT_FAILURE);
}
if (sem_init(&sem, 0, 0) == -1)
handle_error("sem_init");
/* Establish SIGALRM handler; set alarm timer using argv[1] */
sa.sa_handler = handler;
sigemptyset(&sa.sa_mask);
sa.sa_flags = 0;
if (sigaction(SIGALRM, &sa, NULL) == -1)
handle_error("sigaction");
alarm(atoi(argv[1]));
/* Calculate relative interval as current time plus
number of seconds given argv[2] */
if (clock_gettime(CLOCK_REALTIME, &ts) == -1)
handle_error("clock_gettime");
ts.tv_sec += atoi(argv[2]);
printf("main() about to call sem_timedwait()\n");
while ((s = sem_timedwait(&sem, &ts)) == -1 && errno == EINTR)
continue; /* Restart if interrupted by handler */
/* Check what happened */
if (s == -1) {
if (errno == ETIMEDOUT)
printf("sem_timedwait() timed out\n");
else
perror("sem_timedwait");
} else
printf("sem_timedwait() succeeded\n");
exit((s == 0) ? EXIT_SUCCESS : EXIT_FAILURE);
}
VOIR AUSSI
clock_gettime(2), sem_getvalue(3), sem_post(3), sem_overview(7),
time(7)
COLOPHON
Cette page fait partie de la publication 3.27 du projet man-pages
Linux. Une description du projet et des instructions pour signaler des
anomalies peuvent etre trouvees a l'adresse
<URL:http://www.kernel.org/doc/man-pages/>.
TRADUCTION
Depuis 2010, cette traduction est maintenue a l'aide de l'outil po4a
<URL:http://po4a.alioth.debian.org/> par l'equipe de traduction
francophone au sein du projet perkamon
<URL:http://perkamon.alioth.debian.org/>.
Alain Portal <URL:http://manpagesfr.free.fr/> (2006). Nicolas Francois
et l'equipe francophone de traduction de Debian (2006-2009).
Veuillez signaler toute erreur de traduction en ecrivant a
<debian-l10n-french@lists.debian.org> ou par un rapport de bogue sur le
paquet manpages-fr.
Vous pouvez toujours avoir acces a la version anglaise de ce document
en utilisant la commande << man -L C <section> <page_de_man> >>.
Linux 25 fevrier 2010 SEM_WAIT(3)