sem_timedwait(), sem_timedwait_monotonic()

Updated: April 19, 2023

Wait on a named or unnamed semaphore, with a timeout

Synopsis:

#include <semaphore.h>
#include <time.h>

int sem_timedwait( 
        sem_t * sem,
        const struct timespec * abs_timeout );

int sem_timedwait_monotonic(
        sem_t * sem,
        const struct timespec * abs_timeout );

Arguments:

sem
The semaphore that you want to wait on.
abs_timeout
A pointer to a timespec structure that specifies the absolute time at which the timeout is to expire.

Library:

libc

Use the -l c option to qcc to link against this library. This library is usually included automatically.

Description:

The sem_timedwait() function decrements the semaphore referenced by sem as in the sem_wait() function. If the semaphore cannot be decremented (i.e., if the count is 0), the function blocks until another thread increments the semaphore's count, or until the specified timeout expires. The timeout is based on the CLOCK_REALTIME clock.

The sem_timedwait_monotonic() function is a QNX Neutrino extension; it's similar to sem_timedwait(), but it uses CLOCK_MONOTONIC, so the timeout isn't affected by changes to the system time.

If you want to choose the clock against which the timeout is measured, you can instead use sem_clockwait(), which is similar to sem_timedwait() and sem_timedwait_monotonic() and differs only because of its clock parameter (clk). Choosing the clock prevents the timeout from being affected by changes to the system time.

The timeout expires when the absolute time specified by abs_timeout passes, as measured by the clock on which timeouts are based (i.e. when the value of that clock equals or exceeds abs_timeout), or if the absolute time specified by abs_timeout has already been passed at the time of the call.

Returns:

0
The calling thread successfully decremented the semaphore designated by sem.
-1
The call was unsuccessful (errno is set). The state of the semaphore is unchanged.

Errors:

EINTR
A signal interrupted this function.
EINVAL
Invalid semaphore sem, or the thread would have blocked, and the abs_timeout parameter specified a nanoseconds field value less than zero or greater than or equal to 1000 million.
ETIMEDOUT
The semaphore couldn't be decremented before the specified timeout expired.

Examples:

#include <stdio.h>
#include <semaphore.h>
#include <time.h>

main(){

    struct timespec tm;
    sem_t sem;
    int i=0;

    sem_init( &sem, 0, 0);

    do {
        clock_gettime(CLOCK_REALTIME, &tm);
        tm.tv_sec += 1;
        i++;
        printf("i=%d\n",i);
        if (i==10) {
            sem_post(&sem);
        }

    } while ( sem_timedwait( &sem, &tm ) == -1 );

    printf("Semaphore acquired after %d timeouts\n", i);
    return;
}

Classification:

sem_timedwait() is POSIX 1003.1; sem_timedwait_monotonic() is QNX Neutrino

Safety:  
Cancellation point Yes
Interrupt handler No
Signal handler Yes
Thread Yes