You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在C语言中仅捕获子进程终止场景下的SIGCHLD信号

仅通过SIGCHLD追踪子进程终止的实现方法

当然可以不用额外发送SIGUSR1信号,仅通过SIGCHLD就能精准追踪子进程的终止事件,这里有两种可靠的实现方式:

方法一:让父进程只在子进程终止时收到SIGCHLD

通过设置sigaction的SA_NOCLDSTOP标志,就能让系统仅在子进程终止(包括正常退出或被信号杀死)时向父进程发送SIGCHLD,子进程因SIGSTOP等信号停止时不会触发该信号。

示例代码:

#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <sys/wait.h>
#include <unistd.h>

void sigchld_handler(int sig) {
    int status;
    pid_t pid;
    // 循环处理所有已终止的子进程,避免信号丢失(多个子进程可能同时终止)
    while ((pid = waitpid(-1, &status, WNOHANG)) > 0) {
        if (WIFEXITED(status)) {
            printf("子进程 %d 正常终止,退出码:%d\n", pid, WEXITSTATUS(status));
        } else if (WIFSIGNALED(status)) {
            printf("子进程 %d 被信号 %d 终止\n", pid, WTERMSIG(status));
        }
    }
}

int main() {
    struct sigaction sa;
    sa.sa_handler = sigchld_handler;
    sigemptyset(&sa.sa_mask);
    // SA_NOCLDSTOP:子进程停止时不发送SIGCHLD;SA_RESTART:被信号中断的系统调用自动重启
    sa.sa_flags = SA_RESTART | SA_NOCLDSTOP;
    
    if (sigaction(SIGCHLD, &sa, NULL) == -1) {
        perror("sigaction");
        exit(EXIT_FAILURE);
    }

    // 示例:创建子进程
    pid_t child_pid = fork();
    if (child_pid == 0) {
        sleep(2);
        exit(0); // 子进程正常终止
    } else if (child_pid == -1) {
        perror("fork");
        exit(EXIT_FAILURE);
    }

    pause(); // 等待信号
    return 0;
}

方法二:在SIGCHLD处理函数中判断子进程状态

如果需要保留子进程停止时的SIGCHLD信号触发(比如后续可能要处理停止事件),可以不设置SA_NOCLDSTOP,而是在信号处理函数中通过waitpid获取子进程状态,仅处理终止的情况,忽略停止事件。

示例代码:

void sigchld_handler(int sig) {
    int status;
    pid_t pid;
    // WUNTRACED:获取子进程停止的状态
    while ((pid = waitpid(-1, &status, WNOHANG | WUNTRACED)) > 0) {
        if (WIFEXITED(status)) {
            printf("子进程 %d 正常终止\n", pid);
        } else if (WIFSIGNALED(status)) {
            printf("子进程 %d 被信号终止\n", pid);
        }
        // WIFSTOPPED(status)的情况直接忽略,不做处理
    }
}

关键说明

  • 使用waitpid而非wait:waitpid支持非阻塞模式(WNOHANG),能一次性处理所有已终止的子进程,避免信号丢失;同时可以指定选项获取停止状态。
  • 循环调用waitpid:因为SIGCHLD信号是不可靠信号(可能多个子进程终止只触发一次信号),循环调用才能处理所有终止的子进程。

内容的提问来源于stack exchange,提问作者alexstamy

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.15 00:32:44