SIGINT 与其他终止信号(例如 SIGTERM、SIGQUIT 和 SIGKILL)有何关联?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4042201/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-04 23:49:55  来源:igfitidea点击:

How does SIGINT relate to the other termination signals such as SIGTERM, SIGQUIT and SIGKILL?

linuxunixposix

提问by Mecki

On POSIX systems, termination signals usually have the following order (according to many MAN pages and the POSIX Spec):

在 POSIX 系统上,终止信号通常具有以下顺序(根据许多 MAN 页面和 POSIX 规范):

  1. SIGTERM - politely ask a process to terminate. It shall terminate gracefully, cleaning up all resources (files, sockets, child processes, etc.), deleting temporary files and so on.

  2. SIGQUIT - more forceful request. It shall terminate ungraceful, still cleaning up resources that absolutely need cleanup, but maybe not delete temporary files, maybe write debug information somewhere; on some system also a core dump will be written (regardless if the signal is caught by the app or not).

  3. SIGKILL - most forceful request. The process is not even asked to do anything, but the system will clean up the process, whether it like that or not. Most likely a core dump is written.

  1. SIGTERM - 礼貌地要求进程终止。它应正常终止,清理所有资源(文件、套接字、子进程等),删除临时文件等。

  2. SIGQUIT - 更有力的请求。它将终止不优雅的,仍然清理绝对需要清理的资源,但可能不会删除临时文件,可能会在某处写入调试信息;在某些系统上,还会写入核心转储(无论信号是否被应用程序捕获)。

  3. SIGKILL - 最有力的请求。进程甚至不会被要求做任何事情,但系统会清理进程,不管它喜欢与否。很可能写入了核心转储。

How does SIGINT fit into that picture? A CLI process is usually terminated by SIGINT when the user hits CRTL+C, however a background process can also be terminated by SIGINT using KILL utility. What I cannot see in the specs or the header files is if SIGINT is more or less forceful than SIGTERM or if there is any difference between SIGINT and SIGTERM at all.

SIGINT 如何适应那幅画?当用户按下 CRTL+C 时,CLI 进程通常由 SIGINT 终止,但是后台进程也可以使用 KILL 实用程序由 SIGINT 终止。我在规范或头文件中看不到的是 SIGINT 是否比 SIGTERM 更强大或更不强大,或者 SIGINT 和 SIGTERM 之间是否有任何区别。

UPDATE:

更新:

The best description of termination signals I found so far is in the GNU LibC Documentation. It explains very well that there is an intended difference between SIGTERM and SIGQUIT.

迄今为止我发现的对终止信号的最佳描述是在GNU LibC 文档中。它很好地解释了 SIGTERM 和 SIGQUIT 之间的预期差异。

It says about SIGTERM:

它说到 SIGTERM:

It is the normal way to politely ask a program to terminate.

这是礼貌地要求程序终止的正常方式。

And it says about SIGQUIT:

它说的是 SIGQUIT:

[...] and produces a core dump when it terminates the process, just like a program error signal. You can think of this as a program error condition “detected” by the user. [...] Certain kinds of cleanups are best omitted in handling SIGQUIT. For example, if the program creates temporary files, it should handle the other termination requests by deleting the temporary files. But it is better for SIGQUIT not to delete them, so that the user can examine them in conjunction with the core dump.

[...] 并在终止进程时产生核心转储,就像程序错误信号一样。您可以将其视为用户“检测到”的程序错误情况。[...] 在处理 SIGQUIT 时最好省略某些类型的清理。例如,如果程序创建了临时文件,它应该通过删除临时文件来处理其他终止请求。但是 SIGQUIT 最好不要删除它们,以便用户可以结合核心转储来检查它们。

And SIGHUP is also explained well enough. SIGHUP is not really a termination signal, it just means the "connection" to the user has been lost, so the app cannot expect the user to read any further output (e.g. stdout/stderr output) and there is no input to expect from the user any longer. For most apps that mean they better quit. In theory an app could also decide that it goes into daemon mode when a SIGHUP is received and now runs as a background process, writing output to a configured log file. For most daemons already running in the background, SIGHUP usually means that they shall reexamine their configuration files, so you send it to background processes after editing config files.

并且 SIGHUP 也解释得足够好。SIGHUP 并不是真正的终止信号,它只是意味着与用户的“连接”已经丢失,因此应用程序不能期望用户读取任何进一步的输出(例如 stdout/stderr 输出),并且没有期望来自用户不再。对于大多数应用程序,这意味着它们最好退出。理论上,当收到 SIGHUP 并且现在作为后台进程运行时,应用程序也可以决定它进入守护程序模式,将输出写入配置的日志文件。对于大多数已经在后台运行的守护进程,SIGHUP 通常意味着它们将重新检查其配置文件,因此您在编辑配置文件后将其发送到后台进程。

However there is no useful explanation of SIGINT on this page, other than that it is sent by CRTL+C. Is there any reason why one would handle SIGINT in a different way than SIGTERM? If so what reason would this be and how would the handling be different?

然而,在这个页面上没有对 SIGINT 有用的解释,除了它是由 CRTL+C 发送的。是否有任何理由以不同于 SIGTERM 的方式处理 SIGINT?如果是这样,这是什么原因,处理方式会有什么不同?

采纳答案by Matthew Slattery

SIGTERM and SIGKILL are intended for general purpose "terminate this process" requests. SIGTERM (by default) and SIGKILL (always) will cause process termination. SIGTERM may be caught by the process (e.g. so that it can do its own cleanup if it wants to), or even ignored completely; but SIGKILL cannot be caught or ignored.

SIGTERM 和 SIGKILL 用于通用“终止此进程”请求。SIGTERM(默认)和 SIGKILL(总是)将导致进程终止。SIGTERM 可能会被进程捕获(例如,如果它愿意,它可以自己进行清理),甚至完全忽略;但 SIGKILL 不能被捕获或忽略。

SIGINT and SIGQUIT are intended specifically for requests from the terminal: particular input characters can be assigned to generate these signals (depending on the terminal control settings). The default action for SIGINT is the same sort of process termination as the default action for SIGTERM and the unchangeable action for SIGKILL; the default action for SIGQUIT is also process termination, but additional implementation-defined actions may occur, such as the generation of a core dump. Either can be caught or ignored by the process if required.

SIGINT 和 SIGQUIT 专门用于来自终端的请求:可以分配特定的输入字符来生成这些信号(取决于终端控制设置)。SIGINT 的默认操作与 SIGTERM 的默认操作和 SIGKILL 的不可更改操作相同类型的进程终止;SIGQUIT 的默认操作也是进程终止,但可能会发生其他实现定义的操作,例如生成核心转储。如果需要,可以被进程捕获或忽略。

SIGHUP, as you say, is intended to indicate that the terminal connection has been lost, rather than to be a termination signal as such. But, again, the default action for SIGHUP (if the process does not catch or ignore it) is to terminate the process in the same way as SIGTERM etc. .

正如您所说,SIGHUP 旨在表明终端连接已丢失,而不是作为这样的终止信号。但是,同样,SIGHUP 的默认操作(如果进程没有捕获或忽略它)是以与 SIGTERM 等相同的方式终止进程。

There is a table in the POSIXdefinitions for signal.hwhich lists the various signals and their default actions and purposes, and the General Terminal Interfacechapter includes a lot more detail on the terminal-related signals.

POSIX定义中有一个表格,signal.h其中列出了各种信号及其默认操作和用途,通用终端接口一章包含有关终端相关信号的更多详细信息。

回答by Ignacio Vazquez-Abrams

With the exception of a few signals, signal handlers can catch the various signals, or the default behavior upon receipt of a signal can be modified. See the signal(7)man page for details.

除了少数信号外,信号处理程序可以捕获各种信号,或者可以修改接收到信号时的默认行为。有关signal(7)详细信息,请参阅手册页。

回答by DarkDust

Using kill(both the system call and the utility` you can send almost any signal to any process, given you've got the permission. A process cannot distinguish how a signal came to life and who has sent it.

使用kill(系统调用和实用程序),您几乎可以向任何进程发送任何信号,只要您获得许可。进程无法区分信号是如何产生的以及是谁发送的。

That being said, SIGINT really is meant to singal the Ctrl-C interruption, while SIGTERM is the general terminal signal. There is no concept of a signal being "more forceful", with the only exception that there are signals that cannot be blocked or handled (SIGKILL and SIGSTOP, according to the man page).

话虽如此, SIGINT 确实是为了表示 Ctrl-C 中断,而 SIGTERM 是一般的终端信号。没有信号“更有力”的概念,唯一的例外是有些信号无法被阻止或处理(SIGKILL 和 SIGSTOP,根据手册页)。

A signal can only be "more forceful" than another signal with respect to how a receiving process handles the signal (and what the default action for that signal is). For example, by default, both SIGTERM and SIGINT lead to termination. But if you ignore SIGTERM then it will not terminate your process, while SIGINT still does.

在接收进程如何处理信号(以及该信号的默认操作是什么)方面,一个信号只能比另一个信号“更有力”。例如,默认情况下,SIGTERM 和 SIGINT 都会导致终止。但是如果你忽略 SIGTERM 那么它不会终止你的进程,而 SIGINT 仍然会。

回答by Diomidis Spinellis

As DarkDust noted many signals have the same results, but processes can attach different actions to them by distinguishing how each signal is generated. Looking at the FreeBSD kernel source code (kern_sig.c) I see that the two signals are handled in the same way, they terminate the process and are delivered to any thread.

正如 DarkDust 所指出的,许多信号具有相同的结果,但是通过区分每个信号的生成方式,进程可以将不同的操作附加到它们上。查看 FreeBSD 内核源代码 (kern_sig.c) 我看到这两个信号以相同的方式处理,它们终止进程并传递给任何线程。

SA_KILL|SA_PROC,             /* SIGINT */
SA_KILL|SA_PROC,             /* SIGTERM */

回答by Jonathan

After a quick Google search for sigint vs sigterm, it looks like the only intended difference between the two is whether it was initiated by a keyboard shortcut or by an explicit call to kill.

在谷歌快速搜索sigint 与 sigterm 之后,看起来两者之间唯一的区别在于它是由键盘快捷键启动还是通过显式调用kill.

As a result, you could, for example, intercept sigint and do something special with it, knowing that it was likely sent by a keyboard shortcut. Perhaps refresh the screen or something, instead of dying (not recommended, as people expect ^Cto kill the program, just an example).

因此,例如,您可以拦截 sigint 并用它做一些特别的事情,知道它很可能是通过键盘快捷键发送的。也许刷新屏幕什么的,而不是死(不推荐,因为人们希望^C杀死程序,只是一个例子)。

I also learned that ^\should send sigquit, which I may start using myself. Looks very useful.

我还了解到^\应该发送sigquit,我可能会开始使用自己。看起来非常有用。