Убить запущенный вызов подпроцесса



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



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



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

620   4  

4 ответов:

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

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

Ну, есть несколько методов для объекта, возвращаемого 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)

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

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"

Вы можете использовать два сигнала, чтобы убить запущенный вызов подпроцесса, то есть сигнал.SIGTERM и сигнала.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)

Comments

    Ничего не найдено.