2015-09-09 3 views
0

У меня есть сервер Python, который запускает несколько подпроцессов через subprocess.Popen(). Когда я запускаю определенный метод на сервере, я хочу завершить все эти процессы.Правильное закрытие подпроцессов в Python

Мой подход к этому было сохранить ссылки на все процессы в списке ...

self.procs.append(subprocess.Popen(shlex.split(cmd))) 

... и отправить прерывания для всех из них, чтобы закрыть их:

for i, p in enumerate(self.procs) : 
    p.send_signal(signal.SIGINT) 
    print 'interrupted ' + str(i) 
self.procs = [] 

Однако это работает только для некоторых подпроцессов. Например, один из процессов, который не останавливается после этого вызова, - это сценарий bash, который имеет функцию trap для сигналов SIGINT. Если я вручную запустил этот скрипт и прервал его с помощью клавиатуры, он правильно выполнит оператор trap и закроется. Когда сервер посылает сигнал вместо этого, скрипт, похоже, продолжает работать.

Что здесь может быть не так?

Редактировать: Я также попытался использовать сигнал SIGTERM вместо этого, который тоже не работал.

+0

Обычным сигналом для выключения является 'SIGTERM'. Часто у нас может быть задержка «отсрочка» и отправить SIGKILL (например, 'kill -9'), если процесс еще не закрыт. Прерывание может не работать, если сценарий ожидает завершения дочернего процесса в то время. – cdarke

+0

Я также пробовал 'SIGTERM', который до сих пор не решил мою проблему. Кроме того, я предполагаю, что моя проблема имеет свой корень в другом месте, поскольку мой сценарий bash ловушки 'SIGINT' специально, но, похоже, не выполняет оператор trap при получении сигнала с сервера. – zinfandel

+1

Вы пытались 'p.terminate()' или 'p.kill()'? – cdarke

ответ

1

Спасибо всем за ваш вклад, что сработало для меня, в конце концов, был подход, с которым связан Али. Я начал все подпроцессы с этим дополнительным параметром:

preexec_fn=os.setpgrp 

И тогда называли

os.killpg(p.pid, signal.SIGTERM) 

SIGTERM, SIGINT, kill() или terminate() сами по себе не работать для моего сценария оболочки. Сценарий был внутренне запущен двумя службами (sudo service start) и должен был sudo service stop их в функции ловушки, которая не работала должным образом.

У меня действительно были проблемы с другим процессом, который не закрывался - сервер Python, который не был развернут, а просто запущен как скрипт. Не знаю, почему подход killpg не работал с этим. Я, наконец, решил проблему, записав ее pid в файл, а потом родительский скрипт зачитал ее и kill, что pid.

Смежные вопросы