Solved

Programming an asynchronous timer on Linux

Posted on 1998-12-24
6
374 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
Technology Partners: 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 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: IP Lookup

Get more info about an IP address or domain name, such as organization, abuse contacts and geolocation.

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.

Question has a verified solution.

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

Suggested Solutions

Title # Comments Views Activity
Add content to output file 4 72
canBalance challenge 34 109
how to split multiple lines delimiter : 8 130
Windows shortcut location resolution on double click open 4 74
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…
In this post we will learn different types of Android Layout and some basics of an Android App.
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.
A short tutorial showing how to set up an email signature in Outlook on the Web (previously known as OWA). For free email signatures designs, visit https://www.mail-signatures.com/articles/signature-templates/?sts=6651 If you want to manage em…

738 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