#include <semaphore.h> 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 fonctionnalités pour la glibc (consulter feature_test_macros(7)) :
sem_timedwait() :
_POSIX_C_SOURCE >= 200112L
sem_trywait() est pareil à sem_wait(), excepté que si la décrémentation ne peut pas être effectuée immédiatement, l'appel renvoie une erreur (errno vaut EAGAIN) plutôt que de bloquer.
sem_timedwait() est pareil à sem_wait() excepté que abs_timeout spécifie une limite sur le temps pendant lequel l'appel bloquera si la décrémentation ne peut pas être effectuée immédiatement. L'argument abs_timeout pointe sur une structure timespec(3) qui spécifie un temps absolu en secondes et nanosecondes depuis l'époque, 1er janvier 1970 à 00:00:00 (UTC).
Si le délai est déjà expiré à l'heure de l'appel et si le sémaphore ne peut pas être verrouillé immédiatement, sem_timedwait() échoue avec l'erreur d'expiration de délai (errno vaut ETIMEDOUT).
Si l'opération peut être effectuée immédiatement, sem_timedwait() n'échoue jamais avec une valeur d'expiration de délai, quelque soit la valeur de abs_timeout. De plus, la validité de abs_timeout n'est pas vérifiée dans ce cas.
Interface | Attribut | Valeur |
sem_wait(), sem_trywait(), sem_timedwait() | Sécurité des threads | MT-Safe |
$ ./a.out 2 3 main() est sur le point d'appeler sem_timedwait() sem_post() depuis le gestionnaire sem_timedwait() a réussi $ ./a.out 2 1 main() est sur le point d'appeler sem_timedwait() sem_timedwait() a expiré
#include <assert.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() depuis le gestionnaire\n", 24);
if (sem_post(&sem) == -1) {
write(STDERR_FILENO, "sem_post() a échoué\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 <alarme-secs> <attente-secs>\n",
argv[0]);
exit(EXIT_FAILURE);
}
if (sem_init(&sem, 0, 0) == -1)
handle_error("sem_init");
/* Établit le gestionnaire de signal pour SIGALARM ;
fixe le chronomètre de l'alarme selon 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]));
/* Calcule l'intervalle relatif comme l'heure actuelle plus
un certain nombre de secondes données dans argv[2]. */
if (clock_gettime(CLOCK_REALTIME, &ts) == -1)
handle_error("clock_gettime");
ts.tv_sec += atoi(argv[2]);
printf("%s() est sur le point d'appeler sem_timedwait()\n");
while ((s = sem_timedwait(&sem, &ts)) == -1 && errno == EINTR)
continue; /* Redémarre si interrompu par le gestionnaire. */
/* Observe ce qui s'est passé. */
if (s == -1) {
if (errno == ETIMEDOUT)
printf("sem_timedwait() a expiré\n");
else
perror("sem_timedwait");
} else
printf("sem_timedwait() a réussi\n");
exit((s == 0) ? EXIT_SUCCESS : EXIT_FAILURE);
}
Cette traduction est une documentation libre ; veuillez vous reporter à la GNU General Public License version 3 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 à