信号情报如何与其他terminal信号相关?
在POSIX系统上,终止信号通常具有以下顺序(根据许多MAN页面和POSIX规范):
-
SIGTERM – 礼貌地要求一个进程终止。 它将优雅地终止,清理所有资源(文件,套接字,subprocess等),删除临时文件等。
-
SIGQUIT – 更有力的请求。 它将终止不正常,仍然清理绝对需要清理的资源,但可能不会删除临时文件,可能在某处写入debugging信息; 在某些系统上也会写入一个核心转储(不pipe信号是否被应用程序捕获)。
-
SIGKILL – 最有力的请求。 这个过程甚至没有被要求做任何事情,但系统会清理过程,无论是否这样。 最有可能的核心转储写入。
信号情报如何适应这一情况? 当用户点击CRTL + C时,CLI进程通常由SIGINT终止,但后台进程也可以通过使用KILL实用程序的SIGINT终止。 在规范或头文件中我看不到的是SIGINT比SIGTERM更强大还是更差,或者SIGINT和SIGTERM之间有什么区别。
更新:
到目前为止,我发现的终止信号的最佳描述在GNU LibC文档中 。 它很好地解释了SIGTERM和SIGQUIT之间有一个预期的区别。
它说关于SIGTERM:
礼貌地要求程序终止是正常的方法。
它说SIGQUIT:
并在程序终止时产生核心转储,就像程序错误信号一样。 您可以将此视为用户“检测到”的程序错误情况。 在处理SIGQUIT时最好省略某些types的清理。 例如,如果程序创build临时文件,它应该通过删除临时文件来处理其他终止请求。 但是,SIGQUIT最好不要删除它们,以便用户可以与核心转储一起检查它们。
SIGHUP也解释得很好。 SIGHUP不是真正的终止信号,它只是意味着与用户的“连接”已经丢失,所以应用程序不能指望用户读取任何进一步的输出(例如stdout / stderr输出),并且没有input用户不再。 对于大多数应用程序意味着他们更好地退出 理论上,应用程序也可以决定在收到SIGHUP时进入守护程序模式,现在作为后台进程运行,将输出写入configuration的日志文件。 对于大多数已经在后台运行的守护进程来说,SIGHUP通常意味着他们应该重新检查它们的configuration文件,所以在编辑configuration文件之后将它发送到后台进程。
但是在这个页面上没有有用的SIGINT解释,除了它是由CRTL + C发送的。 为什么用SIGTERM不同的方式处理SIGINT有什么原因? 如果是的话,这将是什么原因,如何处理是不同的?
SIGTERM和SIGKILL旨在用于通用目的“终止此进程”请求。 SIGTERM(默认)和SIGKILL(总是)将导致进程终止。 SIGTERM可能被进程所捕获(例如,如果它愿意,它可以自己进行清理),甚至完全忽略; 但SIGKILL不能被捕获或忽略。
SIGINT和SIGQUIT专门用于来自terminal的请求:可以分配特定的input字符来生成这些信号(取决于terminal控制设置)。 SIGINT的缺省操作与SIGTERM的默认操作和SIGKILL的不可更改操作是同一种进程终止; SIGQUIT的默认操作也是进程终止,但可能会发生额外的实现定义的操作,例如生成核心转储。 如果需要的话,任何一个都可以被过程捕捉或忽略。
如您所说,SIGHUP旨在表示terminal连接已经丢失,而不是终止信号。 但是,SIGHUP的默认动作(如果进程没有捕获或忽略)是以与SIGTERM等相同的方式终止进程。
在signal.h
的POSIX定义中有一个表格,列出了各种信号及其默认动作和用途, 通用terminal接口章节包含更多有关terminal相关信号的细节。
正如DarkDust所指出的,许多信号具有相同的结果,但是过程可以通过区分每个信号如何产生来附加不同的行为。 看看FreeBSD的内核源代码(kern_sig.c),我发现这两个信号是以相同的方式处理的,它们终止了这个进程并被传送到任何线程。
SA_KILL|SA_PROC, /* SIGINT */ SA_KILL|SA_PROC, /* SIGTERM */
在对sigint和sigterm进行快速search之后 ,看起来两者之间唯一有意义的区别是它是由键盘快捷方式还是通过显式调用kill
。
因此,例如,你可以拦截sigint并且对它做些特别的事情,知道它可能是通过键盘快捷方式发送的。 也许刷新屏幕或什么,而不是死亡(不推荐,因为人们期望^C
杀死程序,只是一个例子)。
我还了解到应该发送sigquit,我可以开始使用自己的。 看起来非常有用。
一些是ANSI C,而其他则不是
相当不同的是:
- SIGINT和SIGTERM是ANSI C,因此更便于携带
- SIGQUIT和SIGKILL不是
它们在C99草案N1256的 “7.14信号处理”一节中描述:
- SIGINT接收互动关注信号
- SIGTERM发送给程序的终止请求
这使得SIGINT成为一个交互式的Ctrl + C的候选人。
使用kill
(系统调用和实用程序),只要您已经获得许可,您几乎可以将任何信号发送到任何进程。进程无法区分信号是如何发生的以及发送的。
话虽如此,SIGINT确实意味着发出Ctrl-C中断,而SIGTERM是通用terminal信号。 没有信号的概念是“更有力的”,唯一的例外是有信号不能被阻止或处理(SIGKILL和SIGSTOP,根据手册页)。
对于接收过程如何处理信号(以及该信号的默认操作),信号只能比另一个信号“更有力”。 例如,默认情况下,SIGTERM和SIGINT都会导致终止。 但是如果你忽略SIGTERM,那么SIGINT仍然不会终止你的进程。
除less数信号外,信号处理程序可以捕捉各种信号,或者可以修改收到信号时的默认行为。 有关详细信息,请参阅signal(7)
手册页。