为什么我不能用SIGTERM终止SIGSTOP的进程,并且将待处理信号存储在哪里?


24

我正在使用Debian Stretch(systemd)。我在前台使用rsyslog守护程序运行 /usr/sbin/rsyslogd -n ,我做了一个Ctrl+ Z来停止它。进程的状态更改为Tl(已停止,已线程化)。我向流程发出了多个命令,流程的状态是相同的:。一旦我做了一个,它就死了。我有3个问题。kill -15 <pid>Tlfg

  • 为什么SIGSTOP-ed过程没有响应SIGTERM?为什么内核将其保持在相同状态?
  • 为什么收到SIGCONT信号后就被杀死了?
  • 如果是由于先前的SIGTERM信号,在恢复过程之前将其保存在哪里?

Answers:


41

SIGSTOP并且SIGKILL是不能被捕获,并通过一个过程来处理两个信号。SIGTSTP就像SIGSTOP不同的是它可以捕捉和处理。

SIGSTOPSIGTSTP在其轨道的信号停止一个进程,准备好SIGCONT。当您发送该进程a时SIGTERM,该进程未运行,因此无法运行代码以退出。

(还有SIGTTINSIGTTOU,这是TTY层在后台作业尝试读取或写入终端时由TTY层生成的信号。可以捕获它们,但是将停止(挂起)该过程,就像SIGTSTP。但是,我现在要去忽略其余两个答案。)

CtrlZ发送的进程a SIGTSTP似乎并没有以任何方式进行特殊处理rsyslogd,因此它只是挂起挂起的进程SIGCONTSIGKILL

这里的解决方案也是SIGCONT在您之后发送,SIGTERM以便进程可以接收和处理信号。

例:

sleep 999 &

# Assume we got PID 456 for this process
kill -TSTP 456    # Suspend the process (nicely)
kill -TERM 456    # Terminate the process (nicely). Nothing happens
kill -CONT 456    # Continue the process so it can exit cleanly

我认为,GNU C库的文档很好地解释了这一点(重点介绍):

当一个过程停止时,除了SIGKILL信号和(显然)SIGCONT信号之外,没有其他信号可以传递给它,直到继续执行为止。信号被标记为未决,但直到继续处理才交付。SIGKILL信号始终导致过程终止,并且不能被阻塞,处理或忽略。您可以忽略SIGCONT,但是如果停止,它总是使该过程继续进行。向SIGCONT过程发送信号会导致该过程的任何挂起的停止信号被丢弃。同样,SIGCONT当进程接收到停止信号时,该进程的任何挂起信号都将被丢弃


1
@nohup。答案扩展了,但本质上是“是的;它处理了kill -15您已经发送的邮件”。
roaima

2
@nohup是,根据文档:« 进程停止时,在继续执行之前无法向其传递更多信号...信号被标记为未决,但直到继续执行该过程才传递。»
roaima

1
另请参见SIGTTIN和SIGTTOU也停止进程
斯特凡Chazelas

1
@StéphaneChazelas好点。我已经提到了这些,但是忽略了它们。请根据需要随意编辑。
roaima

2
@coteyr。我不同意:SIGKILL防止清除应用程序,因此SIGTERM在许多(大多数)情况下使用更为可取。
roaima

9

SIGTERM就像任何其他信号一样,它可以被进程捕获。接收信号只会使过程跳到特殊的信号处理程序例程。对于SIGTERM默认操作,将终止该过程,但是例如,编辑者可能希望捕获信号,以便它可以在死亡之前保存所有打开文件的草稿副本。如果进程停止,则无法运行信号处理程序,但是信号将保持挂起状态,直到进程继续。请注意,通常不会保存发送的信号数量

从理论上讲,系统可以知道进程是否为安装了信号处理程序SIGTERM,如果没有,则立即终止。但是(根据Gilles的评论),POSIX要求信号将持续发送,直到通过继续该过程SIGCONT


4
抱歉,我之前的评论是错误的。进程停止时,除SIGKILL和SIGCONT外,没有信号传递给该进程。即使信号具有其默认操作(该操作将终止进程),该操作也会延迟到SIGCONT恢复该进程为止。POSIX强制执行此行为。
吉尔(Gilles)'所以
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.