reddi hari
reddi hari

Reputation: 193

how to set multiple Alarms using "setitimer()" function call

I have a requirement to set more than one interval-timers (alarms of same type : ITIMER_REAL) in the same process. so I used setitimer() system call to create 3 alarms with each timer having separate structures to hold time interval values. when any timer expires it will give a signal SIGALRM to the calling process, but i couldn't find which timer among three has given the signal and I don't even know whether all the timers are running or not. Is there any way to find which timer has given the signal... Thank you.

#include <signal.h>
#include <stdio.h>
#include <string.h>
#include <sys/time.h>

void timer_handler (int signum)
{
 static int count = 0;
 printf ("timer1 expired %d times\n", ++count);
}


int main ()
{   
    int m = 0;
     struct sigaction sa;
     struct itimerval timer1, timer2, timer3;

     memset (&sa, 0, sizeof (sa));

     sa.sa_handler = &timer_handler;

     sigaction (SIGALRM/*SIGVTALRM*/, &sa, NULL);

     timer1.it_value.tv_sec = 1;
     timer1.it_value.tv_usec = 0;
     timer1.it_interval.tv_sec = 5;
     timer1.it_interval.tv_usec = 0;

     timer2.it_value.tv_sec = 2;
     timer2.it_value.tv_usec = 0/* 900000*/;
     timer2.it_interval.tv_sec = 5;
     timer2.it_interval.tv_usec = 0/*900000*/;

     timer3.it_value.tv_sec = 3;
     timer3.it_value.tv_usec = 0/* 900000*/;
     timer3.it_interval.tv_sec = 5;
     timer3.it_interval.tv_usec = 0/*900000*/;

     setitimer (ITIMER_REAL/*ITIMER_VIRTUAL*/, &timer1, NULL);
     setitimer (ITIMER_REAL/*ITIMER_VIRTUAL*/, &timer2, NULL);
     setitimer (ITIMER_REAL/*ITIMER_VIRTUAL*/, &timer3, NULL);

    while (1)
    {
        //printf("\nin main  %d",m++);
        //sleep(1);
    }
}

Upvotes: 1

Views: 3515

Answers (2)

Olaf Dietsche
Olaf Dietsche

Reputation: 74018

No, you only have one ITIMER_REAL timer per process. Using setitimer multiple times overwrites the previous value, see man setitimer

A process has only one of each of the three types of timers.

You can also see this, when you modify the intervals in your example code

timer1.it_interval.tv_sec = 1;
timer2.it_interval.tv_sec = 2;

and using nanosleep instead of sleep, because it might interfere with SIGALRM.

Now running the code, you will see only 5 second intervals.


You can also retrieve the previous set value by providing a second struct itimerval

struct itimerval old1, old2, old3;
setitimer(ITIMER_REAL, &timer1, &old1);
setitimer(ITIMER_REAL, &timer2, &old2);
setitimer(ITIMER_REAL, &timer3, &old3);

old1 will contain zero values, because it is the first time you use setitimer. old2 contains it_interval = 1 sec, and old3 contains it_interval = 2 sec. The it_values will be different, depending on how much time elapsed between the calls to setitimer.

So, if you need multiple timers, you need to do some bookkeeping. Each time a timer expires, you must calculate which timer is next and call setitimer accordingly.


As an alternative, you may look into POSIX timers. This allows to create multiple timers

A program may create multiple interval timers using timer_create().

and also pass some id to the handler via sigevent. Although the example at the end of the man page looks a bit more involved.

Upvotes: 1

MartinLeitgeb
MartinLeitgeb

Reputation: 63

If I understand your question right you want to know the status of the different timers.

In the reference a getitimer function avalable:

The function getitimer() fills the structure pointed to by curr_value with the current setting for the timer specified by which (one of ITIMER_REAL, ITIMER_VIRTUAL, or ITIMER_PROF). The element it_value is set to the amount of time remaining on the timer, or zero if the timer is disabled. Similarly, it_interval is set to the reset value.

You can find the full reference here Link

Hope that helps

Upvotes: 0

Related Questions