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

C语言中SIGINT终止子进程时保持父进程存活的实现方法

C语言SIGINT信号仅终止子进程保留父进程的实现方案

该需求可以实现,你提到的「为父进程设置SIGINT信号处理函数、令父进程忽略SIGINT」的方案是可行的,只需要额外处理子进程的信号继承逻辑即可。

默认情况下,用户在终端按下Ctrl+C产生的SIGINT信号会发送给整个前台进程组,父进程和其创建的子进程都属于同一个前台进程组,默认都会收到SIGINT信号,信号的默认动作是终止进程,因此默认情况下父子进程都会同时退出。

核心实现逻辑

  • 父进程注册SIGINT信号的处理规则为忽略,或者注册空的自定义处理函数,让父进程收到SIGINT时不执行默认的终止动作
  • 父进程调用fork()创建子进程后,子进程需要立即将SIGINT的处理规则重置为系统默认动作SIG_DFL(子进程会默认继承父进程的信号处理配置,如果不重置,子进程也会忽略SIGINT无法被终止)
  • 父进程需要监听子进程的退出状态,回收子进程资源避免僵尸进程

完整代码示例

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

int main() {
    // 父进程设置忽略SIGINT信号
    signal(SIGINT, SIG_IGN);
    printf("父进程启动,PID:%d,按下Ctrl+C仅会终止子进程\n", getpid());

    while(1) {
        pid_t pid = fork();
        if (pid < 0) {
            perror("fork失败");
            return 1;
        } else if (pid == 0) {
            // 子进程:重置SIGINT为默认处理动作,收到SIGINT就会终止
            signal(SIGINT, SIG_DFL);
            printf("子进程启动,PID:%d,正在运行...\n", getpid());
            // 子进程模拟业务逻辑
            while(1) {
                sleep(1);
            }
            return 0;
        } else {
            // 父进程:等待子进程退出,回收资源
            int status;
            waitpid(pid, &status, 0);
            if (WIFSIGNALED(status)) {
                printf("子进程%d被信号%d终止,父进程继续运行\n", pid, WTERMSIG(status));
            }
            // 等待2秒后可重新创建子进程,也可以执行其他父进程逻辑
            sleep(2);
            printf("父进程准备重新创建子进程...\n");
        }
    }
    return 0;
}

运行效果说明

编译运行代码后,按下Ctrl+C会看到子进程被终止,父进程不会退出,等待2秒后会重新启动新的子进程。

注意事项

  • 如果需要父进程对SIGINT做额外处理(比如收到SIGINT时先做清理再选择是否退出),可以将signal(SIGINT, SIG_IGN)替换为自定义的信号处理函数,不需要忽略也能实现父进程不终止。
  • 子进程如果调用exec()系列函数加载新的程序,exec执行后所有被设置为忽略/自定义处理的信号都会重置为默认动作,这种情况下子进程可以不用手动重置SIGINT的处理规则。
  • 多次调用signal()设置同一信号的处理规则会覆盖之前的配置,可根据业务需要灵活调整。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 15:45:03