C程序问题:发送SIGTERM信号后子进程未触发处理函数
问题分析与解决方案
嘿,我来帮你拆解下这个问题的核心原因!
问题根源
当你的子进程通过raise(SIGSTOP)进入**暂停状态(Stopped State)**时,它是无法处理普通信号(比如SIGTERM)的。此时你发送的SIGTERM会被标记为"挂起(pending)",但不会触发你注册的信号处理函数,直到子进程被唤醒恢复运行。
你的父进程逻辑是:
- 捕获到子进程暂停后,直接发送
SIGTERM - 立刻调用
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
相关产品推荐
相关产品推荐

