Want to protect your cyber security and still get fast solutions? Ask a secure question today.Go Premium

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 422
  • Last Modified:

Programming an asynchronous timer on Linux

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
nir_m_
Asked:
nir_m_
1 Solution
 
jos010697Commented:
Have you tried the 'alarm' man page?

kind regards,

Jos aka jos@and.nl
0
 
bertvermeerbergenCommented:
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
 
nir_m_Author Commented:
No, I can't use alarm, I need a greater accuracy than full seconds.
0
VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

 
rdelfinoCommented:
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
 
rdelfinoCommented:

Sorry,  I forgot to unblock the SIGALRM.

insert the following lines right before pthread_create():

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

0
 
bertvermeerbergenCommented:
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

Concerto Cloud for Software Providers & ISVs

Can Concerto Cloud Services help you focus on evolving your application offerings, while delivering the best cloud experience to your customers? From DevOps to revenue models and customer support, the answer is yes!

Learn how Concerto can help you.

Tackle projects and never again get stuck behind a technical roadblock.
Join Now