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


103

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

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

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

  3. SIGKILL-最有力的要求。甚至不要求该过程做任何事情,但是系统会清理该过程,无论它是否喜欢。最有可能写入了核心转储。

SIGINT如何适合该图片?用户单击CRTL + C时,CLI进程通常由SIGINT终止,但是SIGINT也可以使用KILL实用程序终止后台进程。我在规范或头文件中看不到的是SIGINT比SIGTERM强多少,或者SIGINT和SIGTERM之间根本没有区别。

更新:

到目前为止,我对终止信号的最佳描述是在GNU LibC文档中。它很好地说明了SIGTERM和SIGQUIT之间存在预期的差异。

它说关于SIGTERM:

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

它说到SIGQUIT:

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

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

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


1
好问题。我怀疑答案中可能涉及到一些历史悠久的Unix问题。
Alex B

我知道这个问题很旧,但是如果有人来这里询问有关您(Linux)操作系统的广泛信号列表,可以sudo fuser -l在命令提示符下键入找到它们。对我来说,这会带来:HUP INT QUIT ILL TRAP ABRT IOT BUS FPE KILL USR1 SEGV USR2 PIPE ALRM TERM STKFLT CHLD CONT STOP TSTP TTIN TTOU URG XCPU XFSZ VTALRM PROF WINCH IO PWR SYS UNUSED
Nick Bull

3
还尝试kill -l获取信号列表。
AAAfarmclub

Answers:


88

SIGTERM和SIGKILL旨在用于一般目的“终止此过程”请求。SIGTERM(默认情况下)和SIGKILL(始终)将导致进程终止。SIGTERM可能会被该进程捕获(例如,以便它可以根据自己的意愿进行清理),甚至被完全忽略。但是SIGKILL不能被捕获或忽略。

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

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

POSIX定义中有一张表格,signal.h其中列出了各种信号及其默认操作和目的,“ 常规终端接口”一章包括与终端相关的信号的更多详细信息。


10
这是关键点:在程序运行时,可以使用单个字符从终端生成SIGINT和SIGQUIT。其他信号必须以某种方式(例如,通过kill命令)由另一个程序生成。SIGINT的暴力程度不如SIGQUIT;后者产生核心转储。SIGKILL无法被困。如果您的连接挂起(窗口关闭等),则会生成SIGHUP。因此,它们都有不同的含义。
乔纳森·莱夫勒

TTY Demystified具有一些易于理解的信息,这些信息涉及信号如何与内核的tty子系统交互。为您的答案添加一些上下文。
DanielNäslund2012年

1
看起来规格不是很精确,但是我的理解是SIgint要求程序停止其当前操作,而不必退出。对于仅设计的程序,每次运行只执行一个动作就意味着退出,但是对于具有某种read-eval-print循环的交互式程序,这可能意味着放弃当前的eval并返回读取用户输入。我认为在sigint上做的很少。
bdsl

重新启动期间发送什么信号?
Dan Dascalescu

10

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

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

9

man 7 signal

这是您经常希望查看Linux信号信息的Linux手册页项目的便捷非规范手册页

版本3.22提到了一些有趣的事情,例如:

无法捕获,阻止或忽略信号SIGKILL和SIGSTOP。

并包含表:

Signal     Value     Action   Comment
----------------------------------------------------------------------
SIGHUP        1       Term    Hangup detected on controlling terminal
                              or death of controlling process
SIGINT        2       Term    Interrupt from keyboard
SIGQUIT       3       Core    Quit from keyboard
SIGILL        4       Core    Illegal Instruction
SIGABRT       6       Core    Abort signal from abort(3)
SIGFPE        8       Core    Floating point exception
SIGKILL       9       Term    Kill signal
SIGSEGV      11       Core    Invalid memory reference
SIGPIPE      13       Term    Broken pipe: write to pipe with no
                              readers
SIGALRM      14       Term    Timer signal from alarm(2)
SIGTERM      15       Term    Termination signal
SIGUSR1   30,10,16    Term    User-defined signal 1
SIGUSR2   31,12,17    Term    User-defined signal 2
SIGCHLD   20,17,18    Ign     Child stopped or terminated
SIGCONT   19,18,25    Cont    Continue if stopped
SIGSTOP   17,19,23    Stop    Stop process
SIGTSTP   18,20,24    Stop    Stop typed at tty
SIGTTIN   21,21,26    Stop    tty input for background process
SIGTTOU   22,22,27    Stop    tty output for background process

Action由于SIGQUIT具有动作Core和SIGINT ,因此总结了区分SIGQUIT和SIGQUIT的信号Term

这些动作记录在同一文档中:

The entries in the "Action" column of the tables below specify the default disposition for each signal, as follows:

Term   Default action is to terminate the process.

Ign    Default action is to ignore the signal.
Core   Default action is to terminate the process and dump core (see core(5)).
Stop   Default action is to stop the process.
Cont   Default action is to continue the process if it is currently stopped.

从内核的角度来看,我看不到SIGTERM和SIGINT之间的任何区别,因为两者都有作用Term并且都可以被捕获。看来这只是“常用用法约定的区别”:

  • 从终端执行CTRL-C时会发生SIGINT
  • SIGTERM是发送的默认信号 kill

有些信号是ANSI C,有些则不是

一个显着的区别是:

  • SIGINT和SIGTERM是ANSI C,因此更具可移植性
  • SIGQUIT和SIGKILL不是

它们在C99 N1256草案的 “ 7.14信号处理”部分中进行了介绍

  • SIGINT收到交互式注意信号
  • SIGTERM将终止请求发送到程序

这使SIGINT成为交互式Ctrl + C的不错选择。

POSIX 7

POSIX 7的signal.h标头记录了信号:https : //pubs.opengroup.org/onlinepubs/9699919799/basedefs/signal.h.html

该页面还具有以下感兴趣的表格,其中提到了我们已经在其中看到的一些内容man 7 signal

Signal    Default Action   Description
SIGABRT   A                Process abort signal.
SIGALRM   T                Alarm clock.
SIGBUS    A                Access to an undefined portion of a memory object.
SIGCHLD   I                Child process terminated, stopped,
SIGCONT   C                Continue executing, if stopped.
SIGFPE    A                Erroneous arithmetic operation.
SIGHUP    T                Hangup.
SIGILL    A                Illegal instruction.
SIGINT    T                Terminal interrupt signal.
SIGKILL   T                Kill (cannot be caught or ignored).
SIGPIPE   T                Write on a pipe with no one to read it.
SIGQUIT   A                Terminal quit signal.
SIGSEGV   A                Invalid memory reference.
SIGSTOP   S                Stop executing (cannot be caught or ignored).
SIGTERM   T                Termination signal.
SIGTSTP   S                Terminal stop signal.
SIGTTIN   S                Background process attempting read.
SIGTTOU   S                Background process attempting write.
SIGUSR1   T                User-defined signal 1.
SIGUSR2   T                User-defined signal 2.
SIGTRAP   A                Trace/breakpoint trap.
SIGURG    I                High bandwidth data is available at a socket.
SIGXCPU   A                CPU time limit exceeded.
SIGXFSZ   A                File size limit exceeded.

BusyBox初始化

BusyBox的1.29.2默认reboot命令将SIGTERM发送到进程,休眠一秒钟,然后发送SIGKILL。这似乎是不同发行版之间的通用约定。

当您通过以下方式关闭BusyBox系统时:

reboot

它向初始化过程发送信号。

然后,init信号处理程序最终调用:

static void run_shutdown_and_kill_processes(void)
{
    /* Run everything to be run at "shutdown".  This is done _prior_
     * to killing everything, in case people wish to use scripts to
     * shut things down gracefully... */
    run_actions(SHUTDOWN);

    message(L_CONSOLE | L_LOG, "The system is going down NOW!");

    /* Send signals to every process _except_ pid 1 */
    kill(-1, SIGTERM);
    message(L_CONSOLE, "Sent SIG%s to all processes", "TERM");
    sync();
    sleep(1);

    kill(-1, SIGKILL);
    message(L_CONSOLE, "Sent SIG%s to all processes", "KILL");
    sync();
    /*sleep(1); - callers take care about making a pause */
}

打印到终端:

The system is going down NOW!
Sent SIGTERM to all processes
Sent SIGKILL to all processes

这是一个最小的具体示例

内核发送的信号


8

在Google快速搜索sigint与sigterm之后,看起来两者之间唯一的预期区别是它是通过键盘快捷键还是通过显式调用发起的kill

结果,例如,您知道它可能是由键盘快捷键发送的,则可以拦截sigint并对其进行特殊处理。也许刷新屏幕或其他内容,而不是死掉(不建议这样做,因为人们希望^C杀死该程序,只是一个例子)。

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


3

使用kill(系统调用和实用程序两者),只要获得您的许可,您就可以将几乎任何信号发送到任何进程。一个进程无法区分信号的产生方式和发送者。

话虽这么说,SIGINT确实意味着要按Ctrl-C中断,而SIGTERM是一般的终端信号。没有信号是“更强大”的概念,唯一的例外是存在无法阻止或处理的信号(根据手册页,SIGKILL和SIGSTOP)。

就接收过程如何处理信号(以及该信号的默认操作是什么)而言,一个信号只能比另一个信号“更强大”。例如,默认情况下,SIGTERM和SIGINT均会导致终止。但是,如果您忽略SIGTERM,则它不会终止您的进程,而SIGINT仍然会终止。


0

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


是的,但是如果我不知道信号的“含义”,那么捕获信号是没有意义的,因为我不知道在应用程序中要做什么。例如,GNU C解释了SIGQUIT和SIGTERM之间的区别。但是它提供的关于SIGINT的信息很少:gnu.org/s/libc/manual/html_node/Termination-Signals.html
Mecki 2010年

SIGINT当用户键入INTR字符时(通常是),将发送(“程序中断”)信号C-c。” “ SIGINT 2术语从键盘中断”您按Ctrl-C,SIGINT将发送。该过程通常会终止。还有什么?
伊格纳西奥·巴斯克斯

可能存在对程序员意图的描述,即程序员在按下ctrl-c(即消息的语义)时应该假定用户将具有的意图。举例来说,HTTP规范明确指出,当用户发送GET请求时,不应假定服务器希望服务器执行除返回响应之外的任何操作。
bdsl
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.