Creating an Absolute Timer

You can use an absolute timer to signal a process at an absolute time, for example at 10:00am tomorrow.

When you create an absolute timer (or a periodic timer) you can set the timer expiry mechanism as one of the following using the sigev_notify member of the sigevent structure:

  • A notification function: Using the notification type, SIGEV_THREAD. For example, you can configure a thread function as an expiry notification.

  • A queued signal: Using the notification type, SIGEV_SIGNAL. For example, you can configure a SIGUSR1 signal as an expiry notification.

    Note: For more information about using signals, see POSIX Signals.

  • No asynchronous notification: Using the notification type, SIGEV_NONE. In this case nothing happens after timer expiry.

Note: For more information about these notification types, see Open Group.

The following example code demonstrates how to create an absolute timer that expires after ten seconds from the time it is set. It also configures the SIGUSR1 signal as an expiry notification using SIGEV_SIGNAL.

The following example code performs the following tasks:

  1. Creates a signal handling function that must be invoked after timer expiry.

  2. Creates a timer based on the current system time (CLOCK_REALTIME) and an asynchronous signal (struct sigevent sig) that must be invoked when the timer expires.

  3. Gets the current system time and stores it in newtime.

  4. Defines the input values for timer_settime(). (Sets an alarm that expires after ten seconds from the time it is set)

  5. Sets the absolute timer using timer_settime().

  6. Uses sleep() to pause execution until the timer expires.

#include <time.h>
#include <stdio.h>
#include <signal.h>
#include <pthread.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
static int I = 0;

//Signal handler function to be invoked when the absolute timer expires
void sig_handler (int val)
    {
    printf("The timer expired and has entered signal handler: Value: %d\n", val);
    }
int main()
    {
    int Ret;

    struct sigevent sig;
    sig.sigev_notify = SIGEV_SIGNAL;
    sig.sigev_signo = SIGUSR1;
    signal(SIGUSR1, sig_handler);
    
    //create a new timer.
    timer_t timerid; //Stores the ID of the timer
    Ret = timer_create(CLOCK_REALTIME, &sig, &timerid);
    if (Ret == 0)
        {
        struct timespec newtime; //Stores the current system time
        struct itimerspec in, out; //Input values for the timer
        memset(&newtime, 0, sizeof (struct timespec)); 
        clock_gettime(CLOCK_REALTIME, &newtime);
        in.it_value.tv_sec = newtime.tv_sec + 10;
        in.it_value.tv_nsec = 0;
        in.it_interval.tv_sec = 0;
        in.it_interval.tv_nsec = 0;
        
        //issue the absolute timer request here.
        Ret = timer_settime(timerid, 1, &in, &out);
        if(Ret == 0)
            sleep(11);
        else
            printf("timer_settime() failed with %d\n", errno);
        //delete the timer.
        timer_delete(timerid);
        }
    else
    printf("timer_create() failed with %d\n", errno);
    return Ret;
}

The output of the above program is:

The timer expired and has entered signal handler: Value: 30

Related concepts