TOC   Previous   Next

POSIX timers

Example code

Create multiple timers, set from command-line arguments

Command-line arguments have form: seconds[:interval-seconds].

#define SIG SIGRTMAX    /* Our timer notification signal */

int
main(int argc, char *argv[])
{
    struct itimerspec ts;
    struct sigaction  sa;
    struct sigevent   sev;
    timer_t *tidlist;        /* Points to list of timer IDs */
    int j;
    char *cptr;

    if (argc < 2)
        usageErr("%s secs[:interval-secs]...\n", argv[0]);

Establish handler for timer notification signal:

    sa.sa_flags = SA_SIGINFO;   /* Pass siginfo_t struct to handler */
    sa.sa_sigaction = handler;
    sigemptyset(&sa.sa_mask);
    if (sigaction(SIG, &sa, NULL) == -1) errExit("sigaction");

Using SA_SIGINFO causes handler to be invoked with a siginfo_t structure as second argument.

The fields that are set in this structure include:

Allocate array to hold timer IDs:

    tidlist = calloc(argc - 1, sizeof(timer_t));
    if (tidlist == NULL) errExit("malloc");

Create one timer for each command-line argument, and start the timers.


    sev.sigev_notify = SIGEV_SIGNAL;
    sev.sigev_signo = SIG;

    /* Set up one timer for each command-line argument */

    for (j = 0; j < argc - 1; j++) {
        sev.sigev_value.sival_ptr = &tidlist[j];
                /* So handler has the address of the timer ID */

        if (timer_create(CLOCK_REALTIME, &sev, &tidlist[j]) == -1)
            errExit("timer_create");
        printf("Timer ID: %ld (%s)\n", (long) tidlist[j], argv[j + 1]);

        ts.it_value.tv_sec = atoi(argv[j + 1]);
		
        cptr = strchr(argv[j + 1], ':');
        ts.it_interval.tv_sec = (cptr != NULL) ? atoi(cptr + 1) : 0;
		
        ts.it_value.tv_nsec = ts.it_interval.tv_nsec = 0;

        if (timer_settime(tidlist[j], 0, &ts, NULL) == -1)
            errExit("timer_settime");
    } 

Wait for signals:

    for (j = 0; ; j++)
        pause();
} /* main */

This is the signal handler:

static void
handler(int sig, siginfo_t *si, void *uc)
{
    timer_t *tidptr = si->si_value.sival_ptr;

    /* UNSAFE: This handler uses non-async-signal-safe functions */

    printf("[%s] Got signal %d\n", currTime("%T"), sig);
    printf("    timer ID           = %d\n", *tidptr);
    printf("    timer_getoverrun() = %d\n", timer_getoverrun(*tidptr));
} /* handler */

(C) 2006, Michael Kerrisk