Витая программа и сигнал TERM - PullRequest
5 голосов
/ 19 июля 2011

У меня есть простой пример:

    from twisted.internet import utils,reactor

    def test:
        utils.getProcessOutput(executable="/bin/sleep",args=["10000"])

    reactor.callWhenRunning(test)
    reactor.run()

когда я посылаю сигнал «TERM» в программу, «сон» продолжает выполняться, когда я нажимаю Ctrl-C при остановке «сна» клавиатуры. (Ctrl-C не является эквивалентом сигнала TERM?) Почему? Как убить "сон" после отправки сигнала "TERM" этой программе?

1 Ответ

4 голосов
/ 19 июля 2011

Ctrl-C отправляет SIGINT всей группе процессов переднего плана. Это означает, что он отправляется в вашу программу Twisted и в дочерний процесс сна.

Если вы хотите завершить спящий процесс всякий раз, когда процесс Python собирается завершиться, тогда вам может потребоваться до завершения триггер:

def killSleep():
    # Do it, somehow

reactor.addSystemEventTrigger('before', 'shutdown', killSleep)

Как написано в вашем примере кода, killSleep сложно реализовать. getProcessOutput не дает вам того, что легко позволяет убить ребенка (например, вы не знаете его pid). Если вы используете 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()) - это то, как отправить его всей группе процессов.

...