Убейте вызов подпроцесса

Я запускаю программу с subprocess на Python.

В некоторых случаях программа может замерзнуть. Это вне моего контроля. Единственное, что я могу сделать из командной строки, которую она запускает, - это Ctrl Esc, которая быстро убивает программу.

Есть ли способ подражать этому с помощью subprocess? Я использую subprocess.Popen(cmd, shell=True) для запуска программы.

Ответ 1

p = subprocess.Popen("echo 'foo' && sleep 60 && echo 'bar'", shell=True)
p.kill()

Ознакомьтесь с документами в модуле subprocess для получения дополнительной информации: http://docs.python.org/2/library/subprocess.html

Ответ 2

Ну, есть несколько методов для объекта, возвращаемого subprocess.Popen(), который может быть полезен: Popen.terminate() и Popen.kill(), которые отправляют SIGTERM и SIGKILL соответственно.

Например...

import subprocess
import time

process = subprocess.Popen(cmd, shell=True)
time.sleep(5)
process.terminate()

... завершит процесс через пять секунд.

Или вы можете использовать os.kill() для отправки других сигналов, например SIGINT для имитации CTRL-C, с...

import subprocess
import time
import os
import signal

process = subprocess.Popen(cmd, shell=True)
time.sleep(5)
os.kill(process.pid, signal.SIGINT)

Ответ 3

Ваш вопрос не слишком ясен, но если я предполагаю, что вы собираетесь запустить процесс, который идет на зомби, и вы хотите иметь возможность контролировать это в каком-то состоянии вашего script. Если это так, я предлагаю вам следующее:

p = subprocess.Popen([cmd_list], shell=False)

Это действительно не рекомендуется проходить через оболочку. Я бы предложил вам использовать shell = False, таким образом вы рискуете меньше переполнения.

# Get the process id & try to terminate it gracefuly
pid = p.pid
p.terminate()

# Check if the process has really terminated & force kill if not.
try:
    os.kill(pid, 0)
    p.kill()
    print "Forced kill"
except OSError, e:
    print "Terminated gracefully"

Ответ 4

Вы можете использовать два сигнала, чтобы убить выполняемый вызов подпроцесса, т.е. сигнал .SIGTERM и signal.SIGKILL; например

import subprocess
import os
import signal
import time
..
process = subprocess.Popen(..)
..
# killing all processes in the group
os.killpg(process.pid, signal.SIGTERM)
time.sleep(2)
if process.poll() is None:  # Force kill if process is still alive
    time.sleep(3)
    os.killpg(process.pid, signal.SIGKILL)