Solved

Programming an asynchronous timer on Linux

Posted on 1998-12-24
6
357 Views
Last Modified: 2013-12-26
I have worked a bit on IBM AIX 4.1.2 and there I had a function called timeout() which would call my given routine every period of time specified. I would like to have the same thing on Linux, I searched for something like timeout() all through the manuals and could not find it.
Ofcourse, I could use select() but that cannot (?) be used asynchronously, i.e the program execution stops until select(| returns.
I am willing to give high points, because it is really important to me, please, HELP!
0
Comment
Question by:nir_m_
6 Comments
 
LVL 4

Expert Comment

by:jos010697
ID: 1294987
Have you tried the 'alarm' man page?

kind regards,

Jos aka jos@and.nl
0
 
LVL 2

Expert Comment

by:bertvermeerbergen
ID: 1294988
Using alarm() and setting up a signal handler that contains the code you want executed is somewhat similar.  There are limitations on what you can do in a signal handler, and alarm() allows you to specify full seconds only, no fractions.  Also, you need to make sure that a system call that is active when the alarm goes off (like select, wait, ...) is restarted, either by your code (checking for errno EINTR) or by the signal implementation itself.  The latter is possible with sigaction() and the other POSIX signal functions, but not (I believe) when using the simple signal() implementation.
0
 

Author Comment

by:nir_m_
ID: 1294989
No, I can't use alarm, I need a greater accuracy than full seconds.
0
Free Tool: Site Down Detector

Helpful to verify reports of your own downtime, or to double check a downed website you are trying to access.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

 
LVL 2

Accepted Solution

by:
rdelfino earned 200 total points
ID: 1294990
In Solaris I have setitimer().

It sets a timer which has greater accuracy than alarm.

If you don't have this function, I suggest you creating a thread that implements the timer
you want.

Something like this:

#define _REENTRANT
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <time.h>
#include <signal.h>
#include <pthread.h>

pthread_attr_t attr;
pthread_t tidTimer;

void *timerThread(void *args);

void yourHandler(int sig);
int main(void)
{
  struct sigaction act;
  sigset_t sigset;
  sigemptyset(&sigset);
  sigaddset(&sigset,SIGALRM);
  sigprocmask(SIG_BLOCK, &sigset, NULL);
 
  act.sa_handler = yourHandler;
  sigemptyset(&act.sa_mask);
  act.sa_flags = SA_SIGINFO;
  sigaction(SIGALRM, &act, NULL);

  pthread_attr_init(&attr);
  pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM);
       
  pthread_create(&tidTimer,  &attr, timerThread, NULL);
 
  /* your program comes here */
 
  return 0;

}

void *timerThread(void *args)
{
  struct timeval timeOut;
  timeOut.tv_sec = 5; /* number of seconds */
  timeOut.tv_usec = 8; /* number of nanoseconds */
  for(;;)
  {
    select(0, NULL, NULL, NULL, &timeOut);
    kill(SIGALRM, getpid());
  }
  return NULL;
}

void yourHandler(int sig)
{
  /* do what you need here */
}


0
 
LVL 2

Expert Comment

by:rdelfino
ID: 1294991

Sorry,  I forgot to unblock the SIGALRM.

insert the following lines right before pthread_create():

sigfillset(&sigset);
sigprocmask(SIG_UNBLOCK, &sigset, NULL);

0
 
LVL 2

Expert Comment

by:bertvermeerbergen
ID: 1294992
If you need sub-second accuracy but you can use the signal handler routine for your code, the solution can be to use setitimer().  This is somewhat similar to alarm(), but lets you specify the delay in seconds + microseconds, much like the select() call.  This call lets you set an interval for a timer that will raise a signal (SIGALRM or another, depending on the options) repeatedly.  Check out the man page for setitimer()/getitimer() for the argument types.
Remark that the microsecond specification is optimistic, normally you will get no more than a 10 millisec granularity (but still much better than the full second).
Also avoid using this in combination with sleep(), alarm() or select() with a timeout.
As a final remark, remember that Linux is not a real-time OS.  The interval you set will be the minimal delay before the signal is raised, but there can be a substantial additional delay before your code gets to handle the signal.  Once you get in to sub-second intervals, this may not be what you are looking for.
If you have problems using the setitimer() and sigacion() calls, I can post a very simple example that I got running here.
0

Featured Post

Free Tool: ZipGrep

ZipGrep is a utility that can list and search zip (.war, .ear, .jar, etc) archives for text patterns, without the need to extract the archive's contents.

One of a set of tools we're offering as a way to say thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
Adapt this command to show who installed 29 111
has77  challenge 9 90
Modbus - whats the maximum I can store in one register? 4 80
Work with App store 7 69
Introduction: Load and Save to file, Document-View interaction inside the SDI. Continuing from the second article about sudoku.   Open the project in visual studio. From the class view select CSudokuDoc and double click to open the header …
Introduction: Dialogs (1) modal - maintaining the database. Continuing from the ninth article about sudoku.   You might have heard of modal and modeless dialogs.  Here with this Sudoku application will we use one of each type: a modal dialog …
This video will show you how to get GIT to work in Eclipse.   It will walk you through how to install the EGit plugin in eclipse and how to checkout an existing repository.
Established in 1997, Technology Architects has become one of the most reputable technology solutions companies in the country. TA have been providing businesses with cost effective state-of-the-art solutions and unparalleled service that is designed…

821 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question