fork() 以及信号如何传递给进程

Nei*_*etz 19 process signals fork

我在 C fork() 的子进程中编写了我编写的程序。两个进程都不会终止。如果我从命令行启动程序并按 control-c 哪个进程将收到中断信号?

Mic*_*mer 30

我们为什么不试试看呢?这是一个简单的程序,signal(3)用于SIGINT在父进程和子进程中捕获并在进程到达时打印出标识该进程的消息。

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
void parent_trap(int sig) {fprintf(stderr, "They got back together!\n");}
void child_trap(int sig) {fprintf(stderr, "Caught signal in CHILD.\n");}
int main(int argc, char **argv) {
    if (!fork()) {
        signal(SIGINT, &child_trap);
        sleep(1000);
        exit(0);
    }
    signal(SIGINT, &parent_trap);
    sleep(1000);
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

让我们称之为test.c。现在我们可以运行它:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
void parent_trap(int sig) {fprintf(stderr, "They got back together!\n");}
void child_trap(int sig) {fprintf(stderr, "Caught signal in CHILD.\n");}
int main(int argc, char **argv) {
    if (!fork()) {
        signal(SIGINT, &child_trap);
        sleep(1000);
        exit(0);
    }
    signal(SIGINT, &parent_trap);
    sleep(1000);
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

终端中产生的中断信号被传递到活动进程组,这里包括 parent 和 child。你可以看到当我按下-时,child_trapparent_trap都被执行了。CtrlC

在 POSIX 中,对fork和 信号之间的交互进行长时间的讨论。这里最重要的部分是:

在 fork() 之后发送到进程组的信号应该传递给父进程和子进程。

他们还指出,某些系统可能不会以完全正确的方式运行,特别是当信号非常接近fork(). 确定您是否在这些系统之一上可能需要阅读代码或很多运气,因为在每次单独尝试中交互几乎不可能。

其他有用的要点是:

  • 一种信号手动生成和发送到单个过程(可能kill)将被递送到该过程中,无论它是否是父或子。
  • 信号处理程序在进程之间运行的顺序未定义,因此您不能依赖于先执行。
  • 如果您没有定义中断处理程序(或显式忽略信号),则两个进程都会以SIGINT代码退出(默认行为)。
  • 如果一个非致命地处理信号而另一个没有,则没有处理程序的一个将死亡,另一个将继续。