为什么subprocess在接收到信号后继续运行?

以下是我的代码。 家长分叉一个孩子。 孩子暂停,直到父母发送一个信号,然后继续运行。 我的问题是为什么在父母发送信号给他之后,subprocess不能继续运行。 我错过或误解了什么?

#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(); } 

以下是父项中发生的情况:

  1. 叉一个孩子。
  2. 发送SIGUSR1给孩子。
  3. 等待一个信号。

这是孩子发生的事情:

  1. 等待一个信号。
  2. 打印Child
  3. 调用kill(0, SIGUSR1) (0是子项中的pid的值)。 使用进程ID为0的调用kill将信号发送到调用kill的进程的进程组中的每个进程。
  4. 等待一个信号。

您的程序有几种可能的行为,具体取决于执行父系和子系统调用的顺序。 根据操作系统的确切版本,各种内核参数的微调,系统的加载情况,以及偶然的机会,如果您多次运行程序或在某个程序下运行程序,可能会也可能不会观察到不同的行为调试器。

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

  1. 家长发送SIGUSR1给孩子。
  2. 孩子收到SIGUSR1并打印Catched
  3. 小孩pause
  4. 家长电话pause

有了这个执行顺序,父母和孩子都会永远等待(这是一个僵局 )。

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

  1. 小孩pause
  2. 家长发送SIGUSR1给孩子。
  3. 家长电话pause
  4. 孩子被解锁并打印Catched
  5. 孩子打印Child
  6. 孩子将SIGUSR1发送给进程组。
  7. 儿童打印Catched
  8. 小孩pause
  9. 家长被解锁并打印Catched
  10. 父母退出。

我不认为有一种方法让孩子退出:它会pause两次,最多可以接收两个信号,其中一个从自己发出( kill(0,SIGUSR1) ),另一个是同步传递的,而不是在执行pause期间。

这个程序可能不是你要写的东西,但是由于你没有描述预期的行为,所以不可能说出你写的意思。 我注意到,你不遵循一个程序的通常结构:

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

尝试这个:

 #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() 。 我添加了一个消除这个。

  3. 这里是示例输出:

 gcc -Wall -g -oz zc ./z Parent Caught Child