Twisted程序与TERM信号
我有一个简单的例子:
from twisted.internet import utils,reactor def test: utils.getProcessOutput(executable="/bin/sleep",args=["10000"]) reactor.callWhenRunning(test) reactor.run()
当我给程序发送“TERM”信号时,“sleep”这个命令还是会继续执行;但是当我在键盘上按下Ctrl-C时,“sleep”就停止了。(Ctrl-C和“TERM”信号不是同一个东西吗?)这是为什么呢?我该怎么做才能在发送“TERM”信号后让“sleep”停止呢?
1 个回答
4
按下 Ctrl-C 会向整个前台进程组发送一个叫做 SIGINT 的信号。这意味着这个信号会同时发送给你的 Twisted 程序和它的一个叫做 sleep 的子进程。
如果你想在 Python 程序退出时杀掉这个 sleep 进程,那么你可能需要一个在关闭之前触发的操作:
def killSleep():
# Do it, somehow
reactor.addSystemEventTrigger('before', 'shutdown', killSleep)
根据你提供的示例代码,killSleep
的实现会比较困难。因为 getProcessOutput
并不会给你一个简单的方法去杀掉这个子进程(比如,你并不知道它的进程 ID)。不过,如果你使用 reactor.spawnProcess
和一个自定义的 ProcessProtocol
,这个问题就能解决了——ProcessProtocol
会连接到一个进程传输上,而这个传输有一个 signalProcess
方法,你可以用它来发送 SIGTERM(或者你想发送的其他信号)给子进程。
你也可以选择忽略 SIGINT,然后手动将这个信号发送给整个进程组:
import os, signal
def killGroup():
signal.signal(signal.SIGINT, signal.SIG_IGN)
os.kill(-os.getpgid(os.getpid()), signal.SIGINT)
reactor.addSystemEventTrigger('before', 'shutdown', killGroup)
忽略 SIGINT 是因为 Twisted 进程已经在关闭了,再发一个信号也没什么用(可能还会让它困惑,或者至少导致一些错误被报告)。发送信号给 -os.getpgid(os.getpid())
就是将信号发送给你整个进程组的方法。