?
Solved

Programming an asynchronous timer on Linux

Posted on 1998-12-24
6
Medium Priority
?
400 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_
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
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
Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
LVL 2

Accepted Solution

by:
rdelfino earned 600 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

Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

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

Introduction: Ownerdraw of the grid button.  A singleton class implentation and usage. Continuing from the fifth article about sudoku.   Open the project in visual studio. Go to the class view – CGridButton should be visible as a class.  R…
If you use Adobe Reader X it is possible you can't open OLE PDF documents in the standard. The reason is the 'save box mode' in adobe reader X. Many people think the protected Mode of adobe reader x is only to stop the write access. But this fe…
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.
Add bar graphs to Access queries using Unicode block characters. Graphs appear on every record in the color you want. Give life to numbers. Hopes this gives you ideas on visualizing your data in new ways ~ Create a calculated field in a query: …
Suggested Courses
Course of the Month13 days, 2 hours left to enroll

777 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