Create all child processes in a new process group, then send the signal to the group.
Up vote 3 down vote favorite 1 share g+ share fb share tw.
Situation: I am writing a program in C that maintains a number of threads. Once a thread ends, a new one is created. Each thread forks - the child runs a process via exec() and the parent waits for it to finish.
In addition, there is a signal handler thread that waits for signals. If SIGINT is detected then it tells the main thread to stop creating threads so eventually all the threads end and the program can exit. Signals are blocked in all threads except of course the signal handler thread.
Aim: I want to be able to terminate the program by sending SIGTERM. This would work by stopping the main thread creating new threads and also terminating the running processes created by threads. Problem: If signals are blocked in all the threads, how can I send a signal to the running processes to terminate them?
Is there some way to make the spawned processes only receive signals sent from the main program and not signals sent to the main program? C multithreading fork signals link|improve this question asked Feb 17 '10 at 14:59SlappyTheFish70429 71% accept rate.
Create all child processes in a new process group, then send the signal to the group. Edit: Here's some minimal code that shows how process can change it's group and control child processes with a signal. #include #include #include #include #include pid_t pgid; /* process group to kill */ void terminator( int s ) /* signal handler */ { printf( "%d:%d received signal %d, exiting\n", getpid(), getpgrp(), s ); exit( 1 ); } int main() /* program entry */ { printf( "%d:%d before first fork\n", getpid(), getpgrp() ); switch ( fork()) /* try with and without first fork */ { case -1: err( 1, "fork" ); case 0: break; default: exit( 0 ); } if ( signal( SIGTERM, terminator ) == SIG_ERR ) err( 1, "signal" ); if ( setpgrp() %d before second fork\n", getpid(), getpgrp(), pgid ); switch ( fork()) { case -1: err( 1, "fork" ); case 0: /* child */ { printf( "child %d:%d\n", getpid(), getpgrp()); sleep( 20 ); break; } default: /* parent */ { printf( "parent %d:%d\n", getpid(), getpgrp()); sleep( 5 ); killpg( pgid, SIGTERM ); sleep( 20 ); } } printf( "%d:%d exiting\n", getpid(), getpgrp()); exit( 1 ); }.
That's exactly what I did but it doesn't seem to work correctly. The group ID I used was the PID of the main thread - is that right? – SlappyTheFish Feb 17 '10 at 15:38 Assuming kill(), are you sending the signal to negative of the group id?
You can also use killpg(). – Nikolai N Fetissov Feb 17 '10 at 16:11 Yes, the main process calls this (pgrp is global): pgrp = getpid(); setpgid(0,0); then the child process created in each thread: setpgid(0,pgrp); And I try and kill the processes like this: killpg(pgrp, SIGTERM); – SlappyTheFish Feb 17 '10 at 16:24 Ok, I see that the groupID of the calling process is the same as its PID, which I use for the groupID of the child processes, which is why the signals never arrive. Any suggestions how to resolve this?
– SlappyTheFish Feb 17 '10 at 16:31 Don't call setpgid(0,pgrp); in the child - the process group id is already inherited. – Nikolai N Fetissov Feb 17 '10 at 17:04.
Create all child processes in a new process group, then send the signal to the group. (thanks Nokolai) Keep records on all processes created and use that to signal them when desired.
I cant really gove you an answer,but what I can give you is a way to a solution, that is you have to find the anglde that you relate to or peaks your interest. A good paper is one that people get drawn into because it reaches them ln some way.As for me WW11 to me, I think of the holocaust and the effect it had on the survivors, their families and those who stood by and did nothing until it was too late.