?
Solved

Linux threads vs signal handler

Posted on 2003-03-31
8
Medium Priority
?
3,927 Views
Last Modified: 2011-10-03
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
0
Comment
Question by:pankaj_garg
[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
8 Comments
 
LVL 6

Accepted Solution

by:
GaryFx earned 1000 total points
ID: 8248017
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
 
LVL 8

Expert Comment

by:akshayxx
ID: 8258393
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
 
LVL 8

Expert Comment

by:akshayxx
ID: 8258408
>>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
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!

 
LVL 8

Expert Comment

by:akshayxx
ID: 8258418
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
 

Author Comment

by:pankaj_garg
ID: 8275186
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
 
LVL 8

Expert Comment

by:akshayxx
ID: 8275343
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
 
LVL 20

Expert Comment

by:jmcg
ID: 10225261
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

Featured Post

Windows Server 2016: All you need to know

Learn about Hyper-V features that increase functionality and usability of Microsoft Windows Server 2016. Also, throughout this eBook, you’ll find some basic PowerShell examples that will help you leverage the scripts in your environments!

Question has a verified solution.

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

Have you ever been frustrated by having to click seven times in order to retrieve a small bit of information from the web, always the same seven clicks, scrolling down and down until you reach your target? When you know the benefits of the command l…
The purpose of this article is to demonstrate how we can upgrade Python from version 2.7.6 to Python 2.7.10 on the Linux Mint operating system. I am using an Oracle Virtual Box where I have installed Linux Mint operating system version 17.2. Once yo…
In this brief tutorial Pawel from AdRem Software explains how you can quickly find out which services are running on your network, or what are the IP addresses of servers responsible for each service. Software used is freeware NetCrunch Tools (https…
Visualize your data even better in Access queries. Given a date and a value, this lesson shows how to compare that value with the previous value, calculate the difference, and display a circle if the value is the same, an up triangle if it increased…
Suggested Courses
Course of the Month12 days, 4 hours left to enroll

752 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