Link to home
Start Free TrialLog in
Avatar of Jelle
Jelle

asked on

Two threads cannot modify the same ITIMER_REAL under Debian Linux?

Hi,

I have a problem.  I have two threads and one sig handler that has to be called around every 100msec . I do this by setting the ITIMER_REAL with the setitimer. This handler is set by one of the two threads.But in a special situation, this signal should not arrive. The other thread notices this during execution and resets the ITIMER_REAL so that it does not deliver any signals any more.
But this does not work. It seems that two different signals are working separately to call the sig handler. Since if I say that the other thread should call the sig handler after 20 msec the sig handler is called twice (once after 20 and once after 100 msec.) So my question is:

How can I let one thread reset the timer for a ITIMER_REAL signal that is set by another thread......


I'm Running on Debian Linux 2.2.17, gcc version 2.95.2 with library -lpthread
Avatar of garboua
garboua

can U post the code where you actually launch the threads, it would be helpful.
Avatar of Jelle

ASKER

In the main the following command is called:
  pthread_t sense;
  SenseHandler s;
  pthread_create( &sense, NULL, sense_callback  , &s);

/**** THREAD 1 ******/
sense_callback looks as follows (argument s to let thread call a method from a class)

void* sense_callback( void *v )
{
  Log.log( 1, "Starting to listen for server messages" );
  SenseHandler* s = (SenseHandler*)v;
  s->handleMessagesFromServer( );
  return NULL;
}

handleMessagesFromServer loops infinite and does the following (among other things):
  struct sigaction sigact;

  sigact.sa_flags = SA_RESTART; // make sure primitives (recvfrom) are not unblocked.
  sigact.sa_handler = (void (*)(int))sigalarmHandler;
  sigaction( SIGALRM, &sigact, NULL );

  itv.it_interval.tv_sec = 0;
  itv.it_interval.tv_usec = 0;
  itv.it_value.tv_sec = 0;

  while( 1 )
  {
    receiveMessage(); // from a socket connection
    .. handle message and determine when signal has to arrive
    itv.it_value.tv_usec = iTimeSignal;
    setitimer( ITIMER_REAL, &itv, NULL );
  }

/**** MAIN THREAD ******/
Main thread does other actions but sometimes want to reset the timer set by thread 1. I do that like this.

  struct itimerval itv2;
  itv2.it_interval.tv_sec = 0;
  itv2.it_interval.tv_usec = 0;
  itv2.it_value.tv_sec = 0;
  itv2.it_value.tv_usec = 0;

  setitimer( ITIMER_REAL, &itv2, NULL );

Strange thing is that this not work. But if I change itv2.it_value.tv_usec to 20*1000, the sigalarmHandler is called twice as many times (so after the signal set by thread 1 and after the signal by the main thread). I like the main thread to destroy the timer that was set was by thread 1. But I don't know how to that....
ASKER CERTIFIED SOLUTION
Avatar of bryanh
bryanh

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of Jelle

ASKER

Thanks, I thought I read somewhere (man pages) that threads under Linux consisted as one process, so I didn't understand why the process' timer hadn't had any effect. I solved it using the variable you mentioned and it seems to work now. Thanks for the help..

Jelle

Statement about two different signals is of course nonsense ;-)
You may have confused pthreads with other kinds of threads.  There are thread libraries (one is called Linuxthreads or something like that) that create threads within one process, without the kernel even knowing about them.  Before pthreads (before Linux 2.2, I think) that was the only way.

I've also heard of other pthreads implementations (not Linux), where pthreads exist within one process until one of them wants to block the process, at which time the process spawns a child to do the waiting.  Linux is nowhere near that complicated.

I'm not an expert on the comparative advantages of threading strategies, but I've heard Linux's thread=process criticized as inefficient.  (I've also heard criticisms that it clutters a 'ps' listing.  Sometimes there are hundreds of threads).
sorry could not get  online for a while, my apology, bryanh did the job though.  if you would like a time to share between all your threads you can download one from sourceforge.  there are plenty timers fully implemented "C++" where you can start the timer and pass class pointer to your threads, and it is easy to interogate the timers.  
www.sourceforge.com and look at snipp code under C++