我的服务器程序收到一个 SIGTERM 并停止(退出代码为 0)。我对此感到惊讶,因为我很确定它有足够的内存。 linux (busybox) 在什么条件下向进程发送 SIGTERM?
答案1
我会将其作为答案发布,以便在出现问题时找到某种解决方案。
退出状态 0 表示正常退出成功的程序。一个退出程序可以选择 0 到 255 之间的任何整数作为其退出状态。按照惯例,程序使用较小的值。 shell 使用 126 及以上的值来报告特殊情况,因此最好避免使用它们。
在 C API 级别,程序报告 16 位状态¶它对程序的退出状态和终止程序的信号(如果有)进行编码。
在外壳中,有一个命令的退出状态(保存在$?
)将程序的实际退出状态和信号值混为一谈:如果程序被信号杀死,则$?
设置为大于 128 的值(对于大多数 shell,该值是 128 加上信号号;ATT ksh使用 256 + 信号号,yash 使用 384 + 信号号,这避免了歧义,但其他 shell 没有效仿)。
特别是,如果$?
为0,则程序正常退出。
请注意,这包括进程接收 SIGTERM,但有一个信号处理程序,并最终正常退出(可能是 SIGTERM 信号的间接结果,也可能不是)的情况。
为了回答您标题中的问题,系统永远不会自动发送 SIGTERM。有一些信号会自动发送,例如终端消失时的 SIGHUP、进程执行不应该执行的操作时的 SIGSEGV/SIGBUS/SIGILL、写入损坏的管道/套接字时的 SIGPIPE 等。由于终端中的按键而发送的一些信号,主要是 SIGINT 用于Ctrl+ C、 SIGQUIT 用于Ctrl+\和 SIGTSTP 用于Ctrl+ Z,但 SIGTERM 不是其中之一。如果一个进程收到 SIGTERM,则其他进程会发送该信号。
1粗略地说
答案2
SIGTERM 是通常用于管理终止进程的信号。
这不是内核会发送的信号,但这是进程通常会发送以终止(优雅)另一个进程的信号。
kill
这是, pkill
, killall
... 命令默认发送的信号。
这是发送到守护进程以停止它们的信号(例如在 a 上service some-service stop
),或者在关闭之前发送init
(对于那些在 SIGTERM 上未能及时终止的进程,后跟 SIGKILL)。
请注意,SIGTERM 是不是发送的信号^C
。发送的信号^C
是SIGINT。