Ответ 1
Если вы действительно хотите действительно поймать C-c, тогда вы можете сделать это обычным способом для приложения Python - используйте signal.signal
для установки обработчика для SIGINT
, который делает все, что вы хотите сделать. Если вы вызываете любые Twisted API из обработчика, убедитесь, что вы используете reactor.callFromThread
, поскольку почти все другие Twisted API небезопасны для вызова обработчиков сигналов.
Однако, если вы действительно заинтересованы в вставке некоторого кода очистки после выключения, то вы, вероятно, захотите использовать IService.stopService
(или механизм, в котором он реализован, reactor.addSystemEventTrigger
).
Если вы используете twistd
, то использовать IService.stopService
легко. У вас уже есть объект Application
, по крайней мере с одним подключенным к нему сервисом. Вы можете добавить еще один с помощью настраиваемого метода stopService
, который будет работать при завершении работы. Возвращается метод Deferred
. Если это так, то процесс останова приостанавливается до тех пор, пока не загорится Deferred
. Это позволяет легко очищать ваши соединения, даже если это связано с некоторыми другими сетевыми (или любыми другими асинхронными) операциями.
Если вы не используете twistd
, то использовать reactor.addSystemEventTrigger
напрямую, вероятно, проще. Вы можете установить триггер до выключения, который вызывается в том же самом случае IService.stopService
. Этот триггер (только любой вызываемый объект) также может вернуть Deferred
для задержки выключения. Это делается при вызове reactor.addSystemEventTrigger('before', 'shutdown', callable)
(когда-то до начала выключения, так что он уже регистрируется всякий раз, когда происходит останов).
service.tac дает пример создания и использования настраиваемой службы.
wxacceptance.py дает пример использования addSystemEventTrigger
и задержки выключения на (произвольное) три секунды.
Оба этих механизма дадут вам уведомление, когда останавливается реактор. Это может быть связано с нажатием клавиши C-c, или может быть, потому что кто-то использовал kill -INT ...
, или может быть, потому что был вызван где-то reactor.stop()
. Все они приводят к остановке реактора, и выключение реактора всегда обрабатывает триггеры аварийного отключения.