Go Premium for a chance to win a PS4. Enter to Win

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

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
0
Jelle
Asked:
Jelle
  • 2
  • 2
  • 2
1 Solution
 
garbouaCommented:
can U post the code where you actually launch the threads, it would be helpful.
0
 
JelleAuthor Commented:
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....
0
 
bryanhCommented:
>It seems that two different signals are working
>separately to call the sig handler.

Since a signal is an event, or a notification of that event, this statement doesn't make sense.  However, I think what you observed is that two different timers are separately generating signals to their own threads.

That's true.  Linux pthreads don't share timers.  In fact, they don't share much at all -- mainly just memory.

A Linux pthread is a process, and a process cannot modify another process' timer.

But it's hard to imagine how you need this function.  Main Thread could just set a variable to tell Thread 1's signal handler to ignore the signal and/or cancel the timer.  Main Thread could also signal Thread 1 so Thread 1 can cancel its timer immediately.
0
 [eBook] Windows Nano Server

Download this FREE eBook and learn all you need to get started with Windows Nano Server, including deployment options, remote management
and troubleshooting tips and tricks

 
JelleAuthor Commented:
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 ;-)
0
 
bryanhCommented:
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).
0
 
garbouaCommented:
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++
0

Featured Post

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!

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