Why doesn't child process continue running after receiving signal?

风流意气都作罢 提交于 2019-12-06 03:51:10

Here's what happens in the parent:

  1. Fork a child.
  2. Send SIGUSR1 to the child.
  3. Wait for a signal.

Here's what happens in the child:

  1. Wait for a signal.
  2. Print Child.
  3. Call kill(0, SIGUSR1) (0 being the value of pid in the child). Calling kill with a process ID of 0 sends the signal to every process in the process group of the process that calls kill.
  4. Wait for a signal.

There are several possible behaviors for your program, depending on the order in which the parent and the child system calls are executed. Depending on the exact version of your operating system, on the fine-tuning of various kernel parameters, on how loaded your system is, and on random chance, you may or may not observe different behavior if you run the program several times or under a debugger.

If the parent starts faster than the child, you may see this:

  1. Parent sends SIGUSR1 to the child.
  2. Child receives SIGUSR1 and prints Catched.
  3. Child calls pause.
  4. Parent calls pause.

With this execution order, both the parent and the child end up waiting forever (it's a deadlock).

If the child starts faster than the parent, you may see this:

  1. Child calls pause.
  2. Parent sends SIGUSR1 to the child.
  3. Parent calls pause.
  4. Child is unblocked and prints Catched.
  5. Child prints Child.
  6. Child sends SIGUSR1 to the process group.
  7. Child prints Catched.
  8. Child calls pause.
  9. Parent is unblocked and prints Catched.
  10. Parent exits.

I don't think there's a way for the child to exit: it calls pause twice, and while it can receive up to two signals, one of these is sent from itself (the one from kill(0,SIGUSR1)) and that one is delivered synchronously, not during the execution of pause.

This program is probably not what you meant to write, but since you don't describe the expected behavior, it's impossible to tell what you did mean to write. I do note that you do not follow the usual structure of a program that forks:

pid = fork();
if (pid < 0) {
    /*error handling*/
} else if (pid == 0) {
    /*child code*/
    exit(...); /*Usually, what follows the if is specific to the parent.*/
}
paulsm4

Try this:

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


void
sigusr1( int pidno )
{
  fprintf(stderr, "Caught\n");
}

int
main()
{
  pid_t pid;

  signal( SIGINT, sigusr1 );
  if( (pid = fork()) == 0 ){
    pause();
    fprintf(stderr, "Child\n");
  }
  else
  {
    fprintf(stderr, "Parent\n");
    kill( pid , SIGINT ); //parent sends signal to child
  }
  pause();
  return 0;
}
  1. printf buffers input: perhaps it's being called, but it isn't being displayed when you expect. One workaround is fflush(). A better workaround is fprintf (stderr), which doesn't buffer in the first place.

  2. You're calling kill() in both the parent and the child. I added an else to eliminate this.

  3. Here's sample output:

gcc -Wall -g -o z z.c

./z
Parent
Caught
Child
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!