|
Home > Archive > Unix Programming > November 2005 > A question about signals
You are viewing an archived Text-only version of the thread.
To view this thread in it's original format and/or if you want to reply to
this thread please [click here]
| Author |
A question about signals
|
|
| 50295@web.de 2005-11-23, 8:50 pm |
| Hi -
I was mucking about with signals trying to see if a parent process can
detect if a child ha stopped and possibly react by restarting it, and
it works using signals and wait (see code below).
The problem is that the parent process appears to be sent a duplicate
SIGCHLD signal because my output looks like this:
Child: I will NOW stop myself (AGAIN)
Parent: my child has stopped. I will NOW restart it ... (handler call)
Parent: my child has stopped. I will NOW restart it ... (duplicate
handler call)
Child: I will NOW stop myself (AGAIN)
Parent: my child has stopped. I will NOW restart it ... (handler call)
Parent: my child has stopped. I will NOW restart it ... (duplicate
handler call)
....
Clearly, the signal handler sigHandler() gets called twice. Why???
Thanks,
- Olumide
/******************************* code *************************/
#include <stdio.h>
#include <signal.h>
#include <sys/wait.h>
int childID;
void sigHandler()
{
printf("Parent: my child has stopped. I will NOW restart it
....\n");
kill(childID, SIGCONT);
}
int main()
{
childID = fork();
if (frv != 0) {
signal(SIGCHLD, sigHandler);
wait(NULL);
}
else { // Child process
while(1)
{
sleep(1);
printf("\tChild: I will NOW stop myself (AGAIN)\n" );
kill(getpid(), SIGSTOP);
}
}
return 0;
}
| |
| Pascal Bourguignon 2005-11-23, 8:50 pm |
| 50295@web.de writes:
> Hi -
>
> I was mucking about with signals trying to see if a parent process can
> detect if a child ha stopped and possibly react by restarting it, and
> it works using signals and wait (see code below).
>
> The problem is that the parent process appears to be sent a duplicate
> SIGCHLD signal because my output looks like this:
>
> Child: I will NOW stop myself (AGAIN)
> Parent: my child has stopped. I will NOW restart it ... (handler call)
> Parent: my child has stopped. I will NOW restart it ... (duplicate
> handler call)
> Child: I will NOW stop myself (AGAIN)
> Parent: my child has stopped. I will NOW restart it ... (handler call)
> Parent: my child has stopped. I will NOW restart it ... (duplicate
> handler call)
> ...
>
>
> Clearly, the signal handler sigHandler() gets called twice. Why???
>
> Thanks,
>
> - Olumide
>
>
> /******************************* code *************************/
>
>
> #include <stdio.h>
> #include <signal.h>
> #include <sys/wait.h>
>
> int childID;
>
> void sigHandler()
> {
> printf("Parent: my child has stopped. I will NOW restart it
> ...\n");
> kill(childID, SIGCONT);
> }
>
> int main()
> {
> childID = fork();
Because here there are TWO processes executing the following.
> if (frv != 0) {
> signal(SIGCHLD, sigHandler);
> wait(NULL);
> }
> else { // Child process
Including here.
> while(1)
> {
> sleep(1);
> printf("\tChild: I will NOW stop myself (AGAIN)\n" );
> kill(getpid(), SIGSTOP);
> }
> }
>
> return 0;
>
> }
- Don't put comments in the code: they lie!
- Do read the manual pages of the function you use!
- Do not use random variable names, use variable names that denote the
actual values, as documented in the man pages!
#define CHILD case 0
#define ERROR case -1
#define PARENT default
pid_t pid;
switch(pid=fork()){
ERROR:
perror("fork");
exit(1);
CHILD:
/* do child stuff */
return(0);
PARENT:
/* do parent stuff */
return(0);
}
--
__Pascal Bourguignon__ http://www.informatimago.com/
Nobody can fix the economy. Nobody can be trusted with their finger
on the button. Nobody's perfect. VOTE FOR NOBODY.
| |
| 50295@web.de 2005-11-23, 8:50 pm |
| I fiddled with the code some more and made the 1 second wait in the
handler 5 seconds so that it now looks like:
void sigHandler()
{
printf("Parent: my child has stopped. I will NOW restart it ...\n");
sleep(5);
kill(childID, SIGCONT);
}
And now there's a much longer delay (5 seconds I reckon). Does sending
a SIGCONT to the child cause another SIGCHLD to be sent to the parent o
what?
- Olumide
PS:
output of /proc/version:
Linux version 2.6.13.2smp (root@...) (gcc version 3.4.4 20050721 (Red
Hat 3.4.4-2)) #6 SMP Wed Oct 19 15:08:23 BST 2005
> - Don't put comments in the code: they lie!
>
> - Do read the manual pages of the function you use!
>
> - Do not use random variable names, use variable names that denote the
> actual values, as documented in the man pages!
Thanks Pascal, but I noticed you didn't answer the question.
| |
| Michael Kerrisk 2005-11-24, 2:48 am |
| On 23 Nov 2005 16:55:54 -0800, 50295@web.de wrote:
>I fiddled with the code some more and made the 1 second wait in the
>handler 5 seconds so that it now looks like:
>
>void sigHandler()
>{
> printf("Parent: my child has stopped. I will NOW restart it ...\n");
> sleep(5);
> kill(childID, SIGCONT);
>}
>
>And now there's a much longer delay (5 seconds I reckon). Does sending
>a SIGCONT to the child cause another SIGCHLD to be sent to the parent o
>what?
On some implementations, including Linux since kernel 2.6.9: yes, a
SIGCHLD is delivered to the parent when one of its children is
restarted by SIGCONT.
Cheers,
Michael
>PS:
>output of /proc/version:
>Linux version 2.6.13.2smp (root@...) (gcc version 3.4.4 20050721 (Red
>Hat 3.4.4-2)) #6 SMP Wed Oct 19 15:08:23 BST 2005
| |
| Maxim Yegorushkin 2005-11-24, 7:48 am |
|
50295@web.de wrote:
> I was mucking about with signals trying to see if a parent process can
> detect if a child ha stopped and possibly react by restarting it, and
> it works using signals and wait (see code below).
If you are making a watch-dog with this method you won't get any
notification if a child has hung or entered a funny state.
A more elaborate method would be if a child sent some keep-alive
signals to the parent periodically or updated a counter in shared
memory, so that the parent could see that a child keeps spinning.
| |
| 50295@web.de 2005-11-24, 5:54 pm |
| Michael Kerrisk wrote:
> On some implementations, including Linux since kernel 2.6.9: yes, a
> SIGCHLD is delivered to the parent when one of its children is
> restarted by SIGCONT.
Thanks Mike ;) .According to the sigaction man page, SIGCHLD is indeed
sent to a parent when its child is killed, stopped, restarted etc
| |
| Daniel C. Bastos 2005-11-26, 2:50 am |
| In article <1132791538.672490.191230@g44g2000cwa.googlegroups.com>,
50295@web.de wrote:
> #include <stdio.h>
> #include <signal.h>
> #include <sys/wait.h>
>
> int childID;
>
> void sigHandler()
> {
> printf("Parent: my child has stopped. I will NOW restart it
> ...\n");
> kill(childID, SIGCONT);
> }
>
> int main()
> {
> childID = fork();
>
> if (frv != 0) {
> signal(SIGCHLD, sigHandler);
> wait(NULL);
> }
What is frv? Notice also that if fork fails, it returns -1 and you
seem to be assuming if fork doesn't return 0, then it's the child
running --- when instead of the child, fork may have failed.
> else { // Child process
>
> while(1)
> {
> sleep(1);
> printf("\tChild: I will NOW stop myself (AGAIN)\n" );
> kill(getpid(), SIGSTOP);
> }
> }
>
> return 0;
>
> }
AFAIK, there's no guarantee that the child will run before or after
the parent --- at least not portably. So I'm wondering here what would
happen if his call to kill in the child runs first than his call to
signal in the parent.
By default, SIGCHLD is ignored, so in case kill runs first, the child
stops itself, the parent misses the SIGCHLD signal and a deadlock
occurs.
It seems that that the OP should be catching the signal before forking.
|
|
|
|
|