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

C程序问题:发送SIGTERM信号后子进程未触发处理函数

问题分析与解决方案

嘿,我来帮你拆解下这个问题的核心原因!

问题根源

当你的子进程通过raise(SIGSTOP)进入**暂停状态(Stopped State)**时,它是无法处理普通信号(比如SIGTERM)的。此时你发送的SIGTERM会被标记为"挂起(pending)",但不会触发你注册的信号处理函数,直到子进程被唤醒恢复运行。

你的父进程逻辑是:

  1. 捕获到子进程暂停后,直接发送SIGTERM
  2. 立刻调用waitpid等待子进程退出

但子进程此时还停在暂停状态,根本没机会处理SIGTERM,自然不会执行sigterm_handler里的退出逻辑,父进程的waitpid就会一直阻塞,导致整个程序停滞。

修复方案

在发送SIGTERM之前,先给子进程发送SIGCONT信号,让它从暂停状态恢复运行。这样挂起的SIGTERM就会被立刻处理,子进程执行完信号处理函数后退出,父进程的waitpid就能正常捕获到退出状态。

修改后的parent.c代码如下:

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

int main(int argc, char* argv[]){
    int status;
    pid_t mem;
    pid_t child = fork();
    if(child == 0){
        char* arr[] = {"./child", NULL};
        execv(arr[0], arr);
    } else if(child > 0){
        mem = child;
        waitpid(mem, &status, WUNTRACED);
    }
    if(WSTOPSIG(status)){
        printf("Sending SIGCONT to wake child\n");
        kill(mem, SIGCONT); // 先唤醒子进程
        printf("Sending SIGTERM to child\n");
        kill(mem, SIGTERM);
        waitpid(mem, &status, 0);
    }
    return 0;
}

补充说明

  • SIGSTOP是Linux中不可捕获、不可忽略的信号,一旦进程收到它,必然会进入暂停状态,这是系统级的强制行为。
  • 处于暂停状态的进程,所有非唤醒类信号都会被暂存为pending状态,直到进程通过SIGCONT恢复运行后,才会依次处理这些挂起的信号。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.06 08:52:38