1

I want to trigger a timer each second for 30 seconds. However, the timer is triggered only once and the program stops. How to make the timer run for 30 seconds?

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

void alarmhandler(){
    printf("\nTimer triggered");
}

void main(){
    struct itimerval timerval;
    signal(SIGALRM, alarmhandler);
    timerval.it_value.tv_sec = 1;
    timerval.it_value.tv_usec = 0;
    timerval.it_interval.tv_sec = 30;
    timerval.it_interval.tv_usec = 0;
    setitimer(ITIMER_REAL, &timerval, 0);
    pause();    
}
Chris Martin
  • 30,334
  • 10
  • 78
  • 137
Saiyan
  • 197
  • 7
  • 22

2 Answers2

0

After receiving a signal your program gets unpaused and it just goes to the end of main() and returns. You need to pause it again, of you want to wait for another signal.

sheikh_anton
  • 3,422
  • 2
  • 15
  • 23
0

One problem you have is the first timer trigger ends the pause call and your program terminates. The pause command is described like this:

The pause function suspends program execution until a signal arrives whose action is either to execute a handler function, or to terminate the process.

Another problem is that you're using the "interval" incorrectly. That value is supposed to be the number that the timer is reset to if it is a repeating timer. So to trigger every second, you need to set it to 1.

Now, if you want it to run for 30 seconds, you'll need to maintain a counter, and then reset the timer after that counter is finished. Finally, you need to keep re-pausing until enough interrupts have been serviced.

Try this:

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

volatile int timer_remain = 30;

void alarmhandler()
{
    static struct itimerval notimer = { 0 };
    printf( "Timer triggered\n" );
    if( --timer_remain == 0 )
    {
        setitimer( ITIMER_REAL, &notimer, 0 );
    }
}

int main()
{
    struct itimerval timerval = { 0 };
    timerval.it_value.tv_sec = 1;
    timerval.it_interval.tv_sec = 1;

    signal( SIGALRM, alarmhandler );
    setitimer( ITIMER_REAL, &timerval, 0 );

    while( timer_remain > 0 )
    {
        pause();
    }

    printf( "Done\n" );
    return 0;
}

One last thing to note is that there's no guarantee that the timer will be delivered every second if system load is high.

paddy
  • 60,864
  • 6
  • 61
  • 103