当父子有一个处理程序时,父shell没有得到SIGINT

当你按下Ctrl-C时,前台进程收到SIGINT:

$ bash -c 'sleep 100; echo program died' ^C $ echo $? 130

但是,如果程序安装了SIGINT处理程序,父程序不会收到信号。 为什么?

#include <unistd.h> #include <signal.h> #include <sys/types.h> #include <stdlib.h> #include <stdio.h> void sig_int(int sig_num) { exit(1); } static struct sigaction sigact = { .sa_handler=sig_int }; int main(int argc,char *argv[]) { sigaction(SIGINT,&sigact,NULL); sleep(100); return 0; }

bash没有死:

$ bash -c './a.out; echo program died' ^Cprogram died

与rsync / subshel​​l exec语句中的Bash没有陷入中断有关 ,但是所有的答案都有解决方法

一个进程如何知道什么时候是背景?

在信号处理程序中接收到信号时会发生什么情况?

将SIGINT信号委派给subprocess,然后清理并终止父进程

在Windows上的信号处理

在LINUX C / C ++中,哪些系统调用是可中断的(即errno == EINTR)?

中止系统调用行为

为什么在这里需要POSIX :: SigSet?

如何将信号名称(string)转换为信号代码

什么是信号(SIGCHLD,SIG_DFL); 意思?

读取信号处理程序中的共享数据

如果不是直接从终端发送,shell会忽略SIGINT

这篇长文章解释了细节中发生的事情。 在这里,我将尝试总结最重要的概念并提出一个工作解决方案。

事实证明,如果shell不是直接从终端发送(按下CTRL-C ),那么shell将被编程为忽略SIGINT 。 如果一个子进程拦截它,那么它必须通过显式地使用SIGINT自杀而退出,引用该帖子:

“如果你没有捕获到SIGINT,系统会自动为你做正确的事情:你的程序退出,在等待退出之后,调用程序会得到正确的”I-ex-on-SIG-SIG“状态。

但是一旦你捕获到了SIGINT,你必须在SIGINT处理程序中进行清理之后,正确地退出

决定SIGINT是否用于退出/中止目的,因此调用该程序的shell脚本应该停止。 这是希望显而易见的。 如果您只需要在SIGINT上进行一些清理,但是立即退出,则答案为“是”。

如果是这样,你必须通过退出“I-ex-SIGIT”状态来告诉调用程序。

除了用SIGINT信号杀死自己以外,没有其他办法可以做到这一点。 通过将SIGINT处理程序重置为SIG_DFL来执行此操作,然后发送自己的信号。

void sigint_handler(int sig) { [do some cleanup] signal(SIGINT,SIG_DFL); kill(getpid(),SIGINT); }

SIGINT处理程序

这是处理程序的工作版本,它拦截信号并正确地杀死自己(因此它不打印“程序死亡”)。 OTOH,如果你发送一个不同的信号,处理程序运行exit功能,你会再次看到“程序死亡”打印在屏幕上。

void sig_int(int sig_num) { if (sig_num == SIGINT) { printf("received SIGINTn"); signal(SIGINT,SIGINT); } else { exit(1); } } static struct sigaction sigact = { .sa_handler=sig_int }; int main(int argc,NULL); printf("go to sleepn"); sleep(3); printf("awakenn"); return 0; }

相关文章

本篇内容主要讲解“gitee如何上传代码”,感兴趣的朋友不妨来...
这篇“从gitee上下的代码如何用”文章的知识点大部分人都不太...
这篇文章主要介绍“gitee如何下载仓库里的项目”,在日常操作...
本篇内容主要讲解“怎么在Gitee上更新代码”,感兴趣的朋友不...
本文小编为大家详细介绍“怎么将工程托管到gitee”,内容详细...
这篇文章主要介绍了gitee中图片大小如何调整的相关知识,内容...