Linux threads vs signal handler

Hi,
  I have a program in which I'm spawning of 3 child processes. The main associates a signal handler (Sigterm and Sigint) and than spawns 3 threads. After this main calls pthread_join to wait for 3 child processes to get over. In the signal handler method, in case the signal is received by one of the threads, I'm re-sending the signal to the main thread. In case it is received by the main thread, I'm not doing anything.

This program works fine on Solaris and program terminates gracefully after sending maximum of 4 signals. But when I run it on Linux, the signal is always received by the main thread. So the program never terminates, even if I send the signal any number of time. How can I rectify the problem? Here is the program.

--------------------------------------------------------------------
#include<iostream.h>
#include <pthread.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#define NTHREADS 4


pthread_t worker[NTHREADS];
pthread_t pid;    

void smServerSignalHandler(int sig_num) {
     cout<<"Got signal "<<sig_num<<" in the handler"<<endl;

        struct sigaction arg;
     arg.sa_handler=smServerSignalHandler;
     sigaction(SIGTERM, &arg, NULL);    
        if (pthread_self() == pid)
     {
          cout<<" pthread_self() == pid xxxxxxxxxxxx Current id"<<endl;

     }
     else
     {
                pthread_kill(SIGTERM,pid);
          cout<<"pthread_self() != pid xxxxxxxxxxxxx NOT Current id"<<endl;
     }
}

//The function hello is being called on the creation of all the 3 threads.
void *hello(void *arg) {
     int myid=*(int*)arg;
     int *status1;
     
     pause();
     
     return (void*)myid;
}

int main(int argc, char *argv[]) {

     int counter[NTHREADS];
     int *status;
     
     pid=pthread_self();

        struct sigaction arg;
     arg.sa_handler=smServerSignalHandler;
     sigaction(SIGTERM, &arg, NULL);    
        if (pthread_self() == pid)

     for(int k=0;k<NTHREADS;k++) {
          int errorcode;

          if ((errorcode=pthread_create(&worker[k],NULL,hello,(void*)&k)) > 0)    
               printf("The error code is %d \n",errorcode);
     }

     for(int l=0;l<NTHREADS;l++) {
         
          //Now the main thread is going to join all the threads.
           pthread_join(worker[l],(void**)&status);
     }
}
-----------------------------------------------------------------------

Regards,
Pankaj
pankaj_gargAsked:
Who is Participating?
 
GaryFxConnect With a Mentor Commented:
I think you have the parameters to pthread_kill in the wrong order.  Apart from that, I don't think there's any way you can guarantee that a SIGTERM sent from outside the process (I'm assuming that's how the first one gets sent) goes to a any specific thread.  You could play games with the thread signal masks, so that the main thread didn't catch it, but then you'd need a different signal to notify it.

Is this just an abstract problem or is there something concrete you're trying to build.  If the latter, you may want to try a different design altogether.

Gary
0
 
akshayxxCommented:
as already said u can use pthread_kill

also have a look at first few paragraphs of the following article..
esp look at the first table.
http://www-106.ibm.com/developerworks/ibm/library/i-signalhandling/
0
 
akshayxxCommented:
>>3 child processes
that means .. no pthreads .. right .. sorry u shud ignore the pthread_kill suggestion..

and for ur case .. i wud suggest parent process shud keep the table of the process id's of itself and the children,

and in your signal_handler fuction, u shud check if the process id is = parent process then .. send kill signal to all the chid process inthe list, and do the clean up..
and if the process id isnt parent.. then do the clean up u wanna do..

try it out , if u r stuck , i can come up with an example of  what i said .. i still hope there might be simpler way .. but for now this is what i can think of

0
Upgrade your Question Security!

Your question, your audience. Choose who sees your identity—and your question—with question security.

 
akshayxxCommented:
once again .. i wud like to take few of my comments back...
 i didnt read ur comment completely and didnt see ur code...
now i saw.. u r using pthread .. so go ahead with pthread_kill..
but please dont say ..
>>spawning 3 child processes

on UNIX systems this means , fork etc .. pthread creates threads and not processes..
its ON linux that..
 Linux threads are just separate processes that share the same address space, so it is also possible for another application to raise a signal on a specific thread

All threads receive the signal, and the signal handler is invoked on each thread.
0
 
pankaj_gargAuthor Commented:
Gary,
   I'm trying to do the same thing as you said, depending on the thread i.e. main or the child thread I want to do something different. But incase of linux the signal always goes to the main thread.
0
 
akshayxxCommented:
then in the signal handler .. send pthread_kill to all the threads.!!.. u'll have to maintain the thread-ids of all the child threads of the current process..
can u show ur piece of code!
0
 
jmcgOwnerCommented:
No comment has been added lately, so it's time to clean up this TA.
I will leave the following recommendation for this question in the Cleanup topic area:

Accept: GaryFx {http:#8248017}

Please leave any comments here within the next seven days.
PLEASE DO NOT ACCEPT THIS COMMENT AS AN ANSWER!

jmcg
EE Cleanup Volunteer
0
All Courses

From novice to tech pro — start learning today.