为了账号安全,请及时绑定邮箱和手机立即绑定

Ctrl-C如何终止子进程?

/ 猿问

Ctrl-C如何终止子进程?

慕哥6287543 2019-11-14 14:42:04

我试图了解CTRL+ 如何C终止子进程而不终止父进程。我在某些脚本外壳中看到了这种行为,例如bash您可以在其中启动一些长时间运行的进程,然后通过输入CTRL- 终止它,然后C控件返回到外壳。

您能解释一下它是如何工作的,尤其是为什么父(shell)进程不会终止?

外壳程序是否必须对CTRLC事件做一些特殊处理,如果是,它到底是做什么的?


查看完整描述

3 回答

?
holdtom

默认情况下,信号由内核处理。旧的Unix系统有15个信号。现在他们有更多。您可以检查</usr/include/signal.h>(或杀死-l)。CTRL+ C是带有名称的信号SIGINT。


内核中也定义了处理每个信号的默认操作,通常它会终止接收信号的进程。


所有信号(但SIGKILL)都可以由程序处理。


这就是shell的作用:


当Shell在交互模式下运行时,此模式具有特殊的信号处理功能。

例如find,运行程序时,shell:

fork本身

并为孩子设置默认信号处理

用给定的命令替换孩子(例如,用find)

当您按CTRL+时C,父级外壳将处理此信号,但子级将收到此信号-带有默认操作-终止。(孩子也可以实现信号处理)

您也可以trap在shell脚本中发出信号...


您也可以为交互式外壳程序设置信号处理,请尝试在您的顶部输入此内容~/.profile。(确保您已经登录并在另一个终端上进行测试-您可以锁定自己)


trap 'echo "Dont do this"' 2

现在,每当您在外壳中按CTRL+ C时,它将打印一条消息。不要忘记删除行!


如果有兴趣,您可以/bin/sh在此处的源代码中检查普通的旧信号处理。


在上面的注释中有一些错误信息(现已删除),因此,如果对此感兴趣的人是一个很好的链接- 信号处理的工作原理。


查看完整回答
反对 回复 2019-11-14
?
郎朗坤

首先,请一直阅读POSIX终端接口上的Wikipedia文章。


该SIGINT信号是由终端线纪律产生,并且广播到终端的中的所有进程前台进程组。您的外壳程序已经为您运行的命令(或命令管道)创建了一个新的进程组,并告诉终端该进程组是其(终端的)前台进程组。每个并发命令管道都有其自己的进程组,而前台命令管道是外壳程序已将其编程到终端中的进程组作为终端的前台进程组的进程。在前台和后台之间切换“工作”(除了一些细节之外)仅是shell告诉终端哪个进程组现在是前台。


Shell进程本身完全位于另一个进程组中,因此当这些进程组之一位于前台时不会接收信号。就这么简单。


查看完整回答
反对 回复 2019-11-14
?
弑天下

终端将INT(中断)信号发送到当前连接到终端的进程。然后,程序会收到它,并可以选择忽略它或退出。


不必强制关闭任何进程(尽管默认情况下,如果您不处理sigint,我相信行为是致电abort(),但我需要查一下)。


当然,正在运行的进程与启动它的外壳是隔离的。


如果您希望使用父外壳,请使用以下命令启动程序exec:


exec ./myprogram

这样,父shell被子进程替换


查看完整回答
反对 回复 2019-11-14

添加回答

回复

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信