signal() inside child process doesn't work??

signal() inside child process doesn't work??

Post by Karthik Dathath » Fri, 17 May 2002 23:34:02



Hello all,
       Below is a C program I tried on a RH Linux 6.0 machine
and compiled using a gcc compiler.The version of the gcc is
2.96
     The output of the program is as follows
"Parent exiting" after some few seconds.

     I tried the same program on an HP-UX 10.20 machine.The output
of the program was:
  signal is received by child
  parent exiting                 (after a few seconds)

     I couldn't understand what could be the problem?

#include <stdio.h>
#include <signal.h>

void abc();
int main(void)
{
   int pid;
   pid = fork();
   if(pid == 0)
   {
      signal(SIGINT,abc);
      sleep(1);
   }
   if (pid > 0 )
   {
      kill(pid,SIGINT);
      sleep(5);
      printf("parent exiting\n");
   }
   return 0;

Quote:}

void abc()
{
   printf("signal is received by child\n");

Quote:}

Thanks
Karthik
 
 
 

signal() inside child process doesn't work??

Post by Steve Kirkendal » Sat, 18 May 2002 01:30:06



> Hello all,
>        Below is a C program I tried on a RH Linux 6.0 machine
> and compiled using a gcc compiler.The version of the gcc is
> 2.96
>      The output of the program is as follows
> "Parent exiting" after some few seconds.

>      I tried the same program on an HP-UX 10.20 machine.The output
> of the program was:
>   signal is received by child
>   parent exiting                 (after a few seconds)

>      I couldn't understand what could be the problem?

There's a race condition -- Can the child call signal() before the parent
calls kill()?  Apparently, when fork() returns under HP-UX the child process
is placed at the front of the kernel's processor queue, while in Linux the
parent process is runs first.  So on Linux, kill() is called before
signal().

You could try fixing it by placing a sleep(1) before the parent's kill(),
and increasing the child's sleep() to sleep(2).  But beware, CPU scheduling
is quirky and makes few promises.

By the way, it's a bad idea to call printf() in a signal handler.  Usually
you just want the signal handler to set a flag, and then have the program
test that flag periodically.  In this example, you would have the child
test the flag after it returns from sleep().

#include <stdio.h>
#include <signal.h>

int flag;
void abc();
int main(void)
{
   int pid;
   pid = fork();
   if(pid == 0)
   {
      signal(SIGINT,abc);
      sleep(2);
      if (flag)
         printf("signal is received by child\n");
   }
   if (pid > 0 )
   {
      sleep(1);
      kill(pid,SIGINT);
      sleep(5);
      printf("parent exiting\n");
   }
   return 0;

Quote:}

void abc()
{
   flag = 1;
Quote:}


 
 
 

signal() inside child process doesn't work??

Post by Kasper Dupon » Sat, 18 May 2002 01:55:19



> There's a race condition -- Can the child call signal() before the parent
> calls kill()?

Maybee that could happen, but actually it is the opposite case
that will give trouble. I guess that is what is going wrong.

Quote:> Apparently, when fork() returns under HP-UX the child process
> is placed at the front of the kernel's processor queue, while in Linux the
> parent process is runs first.  So on Linux, kill() is called before
> signal().

I would guess that Linux would normally schedule the child
before the parent. That is the most efficient in many cases
where the child is going to call exec shortly.

Quote:

> You could try fixing it by placing a sleep(1) before the parent's kill(),
> and increasing the child's sleep() to sleep(2).  But beware, CPU scheduling
> is quirky and makes few promises.

Of course that is a way to verify the assumption about what
is going wrong. But it is not really a solution, the race is
still there.

Quote:

> By the way, it's a bad idea to call printf() in a signal handler.

That is true, but in this particular case it would probably work.
I guess any signal handler interrupting sleep() or pause() can
safely work.

Quote:> Usually
> you just want the signal handler to set a flag, and then have the program
> test that flag periodically.  In this example, you would have the child
> test the flag after it returns from sleep().

Right that would be better.

Quote:

> #include <stdio.h>
> #include <signal.h>

> int flag;

Shouldn't this be initialized?
int flag=0;

Quote:> void abc();

Should actually take an argument
void abc(int sig);

Quote:> int main(void)
> {
>    int pid;

Maybee that is pedantic, but:
pid_t pid;

Quote:>    pid = fork();
>    if(pid == 0)
>    {
>       signal(SIGINT,abc);
>       sleep(2);
>       if (flag)
>          printf("signal is received by child\n");
>    }
>    if (pid > 0 )
>    {
>       sleep(1);
>       kill(pid,SIGINT);
>       sleep(5);
>       printf("parent exiting\n");
>    }
>    return 0;
> }
> void abc()

void abc(int sig)

Quote:> {
>    flag = 1;
> }

--
Kasper Dupont -- der bruger for meget tid p? usenet.

 
 
 

signal() inside child process doesn't work??

Post by Rene Herma » Sat, 18 May 2002 02:08:23



>> int flag;

> Shouldn't this be initialized?
> int flag=0;

C globals are auto-initialised to 0. For maximum safety, it should be
"volatile sig_atomic_t flag;" though.

Rene.