sem_wait(3) Library Functions Manual sem_wait(3) NOM sem_wait, sem_timedwait, sem_trywait - Verrouiller un semaphore BIBLIOTHEQUE Bibliotheque de threads POSIX (libpthread, -lpthread) SYNOPSIS #include int sem_wait(sem_t *sem); int sem_trywait(sem_t *sem); int sem_timedwait(sem_t *restrict sem, const struct timespec *restrict abs_timeout); Exigences de macros de test de fonctionnalites pour la glibc (consulter feature_test_macros(7)) : sem_timedwait() : _POSIX_C_SOURCE >= 200112L DESCRIPTION sem_wait() decremente (verrouille) le semaphore pointe par sem. Si la valeur du semaphore est plus grande que zero, la decrementation s'effectue et la fonction renvoie immediatement. Si le semaphore vaut zero, l'appel bloquera jusqu'a ce qu'il devienne possible d'effectuer la decrementation (c'est-a-dire la valeur du semaphore devient positive) ou qu'un gestionnaire de signaux interrompe l'appel. sem_trywait() est pareil a sem_wait(), excepte que si la decrementation ne peut pas etre effectuee immediatement, l'appel renvoie une erreur (errno vaut EAGAIN) plutot que de bloquer. sem_timedwait() est pareil a 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 timespec(3) qui specifie un temps absolu en secondes et nanosecondes depuis l'epoque, 1er janvier 1970 a 00:00:00 (UTC). 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 RENVOYEE 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 EAGAIN (sem_trywait()) L'operation ne peut pas etre effectuee sans bloquer (c'est-a-dire, le semaphore a une valeur nulle). EINTR L'appel a ete interrompu par un gestionnaire de signal ; consultez signal(7). EINVAL sem n'est pas un semaphore valable. EINVAL (sem_timedwait()) La valeur de abs_timeout.tv_nsecs est plus petite que 0 ou superieure ou egale a 1 milliard. ETIMEDOUT (sem_timedwait()) Le delai a expire avant que le semaphore ait pu etre verrouille. ATTRIBUTS Pour une explication des termes utilises dans cette section, consulter attributes(7). +---------------------------------+--------------------------+---------+ |Interface | Attribut | Valeur | +---------------------------------+--------------------------+---------+ |sem_wait(), sem_trywait(), | Securite des threads | MT-Safe | |sem_timedwait() | | | +---------------------------------+--------------------------+---------+ STANDARDS POSIX.1-2008. HISTORIQUE POSIX.1-2001. EXEMPLES 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 main() est sur le point d'appeler sem_timedwait() sem_post() depuis le gestionnaire sem_timedwait() a reussi $ ./a.out 2 1 main() est sur le point d'appeler sem_timedwait() sem_timedwait() a expire Source du programme #include #include #include #include #include #include #include #include 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 \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("%s() about to call sem_timedwait()\n", __func__); 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), timespec(3), sem_overview(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 sem_wait(3)