如何让父进程忽略SIGINT信号而子进程不忽略?
父进程忽略SIGINT但exec子进程正常响应的解决方法
问题根源:
父进程调用signal(SIGINT, SIG_IGN)忽略SIGINT后,fork()创建的子进程会完全继承父进程的信号处理配置,因此子进程默认也会忽略SIGINT。而execvp()执行新程序时,被显式设置为忽略的信号不会自动重置,只有默认处理的信号会保持默认行为,导致子进程依然不响应SIGINT。
解决方案:
在fork()之后、execvp()之前,在子进程代码中将SIGINT的处理方式恢复为默认(SIG_DFL),再执行目标程序。
代码示例:
#include <stdio.h> #include <signal.h> #include <unistd.h> #include <sys/wait.h> int main() { // 父进程设置忽略SIGINT signal(SIGINT, SIG_IGN); pid_t pid = fork(); if (pid == -1) { perror("fork failed"); return 1; } if (pid == 0) { // 子进程恢复SIGINT为默认处理 signal(SIGINT, SIG_DFL); // 执行目标程序,这里以ls为例 char *cmd_args[] = {"ls", "-l", NULL}; execvp(cmd_args[0], cmd_args); // execvp执行失败才会到达此处 perror("execvp failed"); return 1; } else { // 父进程等待子进程退出 wait(NULL); } return 0; }
说明:
- 父进程保持对SIGINT的忽略状态,按下Ctrl+C不会终止父进程。
- 子进程在exec前恢复SIGINT的默认处理,因此exec后的新程序会正常响应SIGINT(收到信号后终止)。
- 必须在子进程中显式恢复信号处理,不能依赖exec自动重置忽略状态。
内容的提问来源于stack exchange,提问作者Ido Amit
相关产品推荐
相关产品推荐

