views:

183

answers:

1

Can anyone illustrate the use of settimer or alarm function in gnu C , with some program examples ,please ?

I have a program that continuously processes some data , and i need to set a timer / alarm that goes off every t seconds , in response to which , i need to store the processed data into a file. This file writing has to be asynchronous < i.e. the data processing and file writing must not wait for each other > . I went through the GNU C Library pages , but i couldn't understand much..

[EDIT]

I got this program :

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

#define INTERVAL 1

int howmany = 0;

void alarm_wakeup (int i)
{
   struct itimerval tout_val;

   signal(SIGALRM,alarm_wakeup);

   howmany += INTERVAL;

   printf("\n%d sec up partner, Wakeup!!!\n",howmany);
   tout_val.it_interval.tv_sec = 0;
   tout_val.it_interval.tv_usec = 0;
   tout_val.it_value.tv_sec = INTERVAL; /* 10 seconds timer */
   tout_val.it_value.tv_usec = 0;

   setitimer(ITIMER_REAL, &tout_val,0);

}

void exit_func (int i)
{
    signal(SIGINT,exit_func);
    printf("\nBye Bye!!!\n");
    exit(0);
}

int main ()
{
  struct itimerval tout_val;

  tout_val.it_interval.tv_sec = 0;
  tout_val.it_interval.tv_usec = 0;
  tout_val.it_value.tv_sec = INTERVAL; /* 10 seconds timer */
  tout_val.it_value.tv_usec = 0;
  setitimer(ITIMER_REAL, &tout_val,0);

  signal(SIGALRM,alarm_wakeup); /* set the Alarm signal capture */
  signal(SIGINT,exit_func);

  while (1)
  {
    //printf("!");
  }

  return 0;

}

But seems like i cannot do anything while the timer is on.. What should i modify to suit my needs ? Pl suggest.. [/EDIT]

A: 

Here's an example from here which uses setitimer() to periodically call DoStuff().

The key here is that calling setitimer() results in the OS scheduling a SIGALRM to be sent to your process after the specified time has elapsed, and it is up to your program to handle that signal when it comes. You handle the signal by registering a signal handler function for the signal type (DoStufF() in this case) after which the OS will know to call that function when the timer expires.

You can read the setitimer() man page to figure out what the arguments are and how to cancel a timer.

Note: if you want the timer to trigger only once, you will have to call alarm() or ualarm() instead of setitimer().

/*
 * setitimer.c - simple use of the interval timer
 */

#include <sys/time.h>       /* for setitimer */
#include <unistd.h>     /* for pause */
#include <signal.h>     /* for signal */

#define INTERVAL 500        /* number of milliseconds to go off */

/* function prototype */
void DoStuff(void);

int main(int argc, char *argv[]) {

  struct itimerval it_val;  /* for setting itimer */

  /* Upon SIGALRM, call DoStuff().
   * Set interval timer.  We want frequency in ms, 
   * but the setitimer call needs seconds and useconds. */
  if (signal(SIGALRM, (void (*)(int)) DoStuff) == SIG_ERR) {
    perror("Unable to catch SIGALRM");
    exit(1);
  }
  it_val.it_value.tv_sec =     INTERVAL/1000;
  it_val.it_value.tv_usec =    (INTERVAL*1000) % 1000000;   
  it_val.it_interval = it_val.it_value;
  if (setitimer(ITIMER_REAL, &it_val, NULL) == -1) {
    perror("error calling setitimer()");
    exit(1);
  }

  while (1) 
    pause();

}

/*
 * DoStuff
 */
void DoStuff(void) {

  printf("Timer went off.\n");

}
liwp
Thanks for that , how do i modify this if i want this whole alarm running as a background , meanwhile i can process some data.. and as n when the alarm goes off , i write something to a file.. as i said before , both these i.e. processing and file writing to be asyncronous..
trinity
Thanks a lot , i made a few changes to this program and i nearly got what i wanted.. ( I'm now going to try it for the packet capture project i'm currently working in )
trinity
In your code you end up spinning in main(), so instead of the empty loop you could do your processing there. Whenever you get the SIGALRM your code will be paused and the signal handler gets control. Once the signal handler finishes, your code will continue again. So you could use the signal handler to set a flag indicating that you should write to a file and then check that flag in your processing loop. If it's set, you'll write to the file and reset the flag to false. But this solution is not asynchronous, i.e. the alarm / signal handler will only set a flag rather than write file.
liwp
(I ran out of space above) You have to be careful when writing the file so that your data structure that you're writing is in a consistent state rather than being modified by the main process. That's why the flag-setting approach is good.
liwp