接收信号后,为什么子进程不继续运行?

时间:2011-09-25 16:21:54

标签: unix process fork signals

以下是我的代码。父母要求孩子。子项暂停直到父发送信号给它,然后它继续运行。 我的问题是为什么儿童过程不继续 在父母向他发送信号后运行。我错过了什么或误解了什么吗?

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


void 
sigusr1( int pidno )
{
  printf("Catched\n");
}

int 
main()
{
  pid_t pid;

  signal( SIGUSR1, sigusr1 );
  if( (pid = fork()) == 0 ){
    pause();
  printf("Child\n"); 
  }

  kill( pid , SIGUSR1 ); //parent sends signal to child 
  pause();
}

2 个答案:

答案 0 :(得分:3)

以下是父母所发生的事情:

  1. 分叉一个孩子。
  2. 将SIGUSR1发送给孩子。
  3. 等待信号。
  4. 以下是孩子的情况:

    1. 等待信号。
    2. 打印Child
    3. 调用kill(0, SIGUSR1)(0是孩子中pid的值)。调用进程ID为0的kill会将信号发送到调用kill的进程的process group中的每个进程。
    4. 等待信号。
    5. 您的程序有几种可能的行为,具体取决于执行父系统调用和子系统调用的顺序。根据操作系统的确切版本,微调各种内核参数,系统加载方式以及随机机会,如果您多次运行程序或在运行程序下,您可能会或可能不会观察到不同的行为调试器。

      如果父母的开始时间比孩子快,您可能会看到:

      1. 父母将SIGUSR1发送给孩子。
      2. 儿童收到SIGUSR1并打印Catched
      3. 儿童来电pause
      4. 家长致电pause
      5. 有了这个执行顺序,父母和孩子都会永远等待(这是deadlock)。

        如果孩子比父母开始得快,你可能会看到:

        1. 儿童来电pause
        2. 父母将SIGUSR1发送给孩子。
        3. 家长致电pause
        4. 取消阻止儿童并打印Catched
        5. 儿童打印Child
        6. Child将SIGUSR1发送到进程组。
        7. 儿童打印Catched
        8. 儿童来电pause
        9. 取消屏蔽父级并打印Catched
        10. 家长退出。
        11. 我认为孩子没有办法退出:它会调用pause两次,虽然它最多可以接收两个信号,但其中一个是自己发送的({{1并且那个是同步传递的,而不是在执行kill(0,SIGUSR1)期间传递的。

          这个程序可能不是你想要编写的,但由于你没有描述预期的行为,所以不可能分辨你写的意思。我注意到你没有遵循分叉程序的通常结构:

          pause

答案 1 :(得分:1)

试试这个:

#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缓冲区输入:可能正在调用它,但是在您预期时它不会显示。一种解决方法是fflush()。一个更好的解决方法是fprintf (stderr),它首先不缓冲。

  2. 您正在父母和孩子中调用kill()。我添加了else来消除此问题。

  3. 以下是示例输出:

  4. gcc -Wall -g -o z z.c
    
    ./z
    Parent
    Caught
    Child