fork 后调用信号

标签 c linux fork signals signal-handling

“代码 list 1”和“代码 list 2”有区别吗?因为在代码 list 1 中,子进程能够捕获 SIGTERM 信号并正常退出。但是代码 list 2 在收到 SIGTERM 信号时突然终止。

我正在使用 Linux 和 C。

代码 list 1

if (signal(SIGTERM, stopChild) == SIG_ERR) {
    printf("Could not attach signal handler\n");
    return EXIT_FAILURE;
}
pid = fork();

代码 list 2

pid = fork();
if (signal(SIGTERM, stopChild) == SIG_ERR) {
    printf("Could not attach signal handler\n");
    return EXIT_FAILURE;
}

奇怪的是,在代码 list 2 中,子进程和父进程都为 SIGTERM 设置了信号处理程序。所以,这应该有效。不是吗?

最佳答案

如果您从父级发送 SIGTERM,最终结果取决于进程的调度顺序。

如果 child 先被安排好,一切正常:

                                                +---------------+
                                                | pid = fork(); |
                                                +-------+-------+
                   parent                               |                               child
                          +-----------------------------+-----------------------------+
                          |                                                           |
                          |                                 +-------------------------+--------------------------+
                          |                                 | if (signal(SIGTERM, stopChild) == SIG_ERR) {       |
                          |                                 |       printf("Could not attach signal handler\n"); |
                          |                                 |       return EXIT_FAILURE;                         |
                          |                                 | }                                                  |
                          |                                 +-------------------------+--------------------------+
                          |                                                           |
                          .                                                           .
                          .                                                           .
                          .                                                           .
                          |                                                           |
+-------------------------+--------------------------+                                |
| if (signal(SIGTERM, stopChild) == SIG_ERR) {       |                                |
|       printf("Could not attach signal handler\n"); |                                |
|       return EXIT_FAILURE;                         |                                |
| }                                                  |                                |
+-------------------------+--------------------------+                                |
                          |                                                           |
                          |                                                           |
                          |                                                           |
            +-------------+-------------+                                             |
            | if (pid > 0) {            |                                             |
            |       kill(pid, SIGTERM); |                                             |
            | }                         |                                             |
            +-------------+-------------+                                             |
                          |                                                           |
                          |                                                           |
                          |                                                           |

但是如果 parent 先被调度, child 可能没有时间设置信号处理程序:

                                                +---------------+
                                                | pid = fork(); |
                                                +-------+-------+
                   parent                               |                               child
                          +-----------------------------+-----------------------------+
                          |                                                           |
+-------------------------+--------------------------+                                |
| if (signal(SIGTERM, stopChild) == SIG_ERR) {       |                                |
|       printf("Could not attach signal handler\n"); |                                |
|       return EXIT_FAILURE;                         |                                |
| }                                                  |                                |
+-------------------------+--------------------------+                                |
                          |                                                           |
                          |                                                           |
                          |                                                           |
            +-------------+-------------+                                             |
            | if (pid > 0) {            |                                             |
            |       kill(pid, SIGTERM); |                                             |
            | }                         |                                             |
            +-------------+-------------+                                             |
                          |                                                           |
                          .                                                           .
                          .                                                           .
                          .                                                           .
                          |                                                           |
                          |                                 +-------------------------+--------------------------+
                          |                                 | if (signal(SIGTERM, stopChild) == SIG_ERR) {       |
                          |                                 |       printf("Could not attach signal handler\n"); |
                          |                                 |       return EXIT_FAILURE;                         |
                          |                                 | }                                                  |
                          |                                 +-------------------------+--------------------------+
                          |                                                           |
                          |                                                           |
                          |                                                           |

这称为竞争条件,因为最终结果取决于谁先跑。

关于 fork 后调用信号,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4828603/

相关文章:

perl - 如何在 Perl 中管理 fork 池?

git - 无法 fork DevOps git repo-服务不受支持

c++ - 是否可以在 C++ 中放入通信 2 fork()?

c - 如何修改已传递给 C 函数的指针?

c - 在C中读取和写入unicode字符到文件

c - #if 为预处理器指令定义字符串比较

linux - 删除vim文件中的一些字符

linux - 在Linux中使用文件名和文件内容创建CSV文件

javascript - 你如何调用一个 C 函数,它通过 Emscripen/Wasm 从 JS 中按值获取(或返回)一个结构?

linux - 如何从系统中的任何位置(当前目录之外)运行我的脚本?