Я запускаю подпроцесс с помощью следующей команды:
p = subprocess.Popen(cmd, stdout=subprocess.PIPE, shell=True)
Тем не менее, когда я пытаюсь убить с помощью:
p.terminate()
или
p.kill()
Команда продолжает работать в фоновом режиме, поэтому мне было интересно, как я могу на самом деле завершить процесс.
Обратите внимание, что когда я запускаю команду с:
p = subprocess.Popen(cmd.split(), stdout=subprocess.PIPE)
Он завершается успешно при выдаче p.terminate()
.
python
linux
subprocess
kill-process
user175259
источник
источник
cmd
выглядишь? Он может содержать команду, запускающую несколько процессов. Так что не ясно, о каком процессе вы говорите.shell=True
большого значения?Ответы:
Используйте группу процессов, чтобы разрешить отправку сигнала всем процессам в группах. Для этого вы должны прикрепить идентификатор сеанса к родительскому процессу порожденных / дочерних процессов, который является оболочкой в вашем случае. Это сделает его лидером группы процессов. Итак, теперь, когда сигнал отправляется руководителю группы процессов, он передается всем дочерним процессам этой группы.
Вот код:
источник
os.setsid
не доступен в Windows ( docs.python.org/library/os.html#os.setsid ), я не знаю, может ли это помочь, но вы можете посмотреть здесь ( bugs.python.org / Issue 5115 ) для некоторых о том, как это сделать.subprocess.CREATE_NEW_PROCESS_GROUP
отношение это имеет к этому?CREATE_NEW_PROCESS_GROUP
может использоваться для эмуляцииstart_new_session=True
в Windowsp.kill()
заканчивает тем, что убил процесс оболочки иcmd
все еще работает.Я нашел удобное решение этой проблемы:
Это заставит cmd наследовать процесс оболочки вместо того, чтобы оболочка запускала дочерний процесс, который не был уничтожен.
p.pid
будет идентификатором вашего процесса cmd тогда.p.kill()
должно сработать.Я не знаю, какое влияние это окажет на вашу трубу.
источник
Если вы можете использовать psutil , то это прекрасно работает:
источник
AttributeError: 'Process' object has no attribute 'get_children
дляpip install psutil
.Я мог бы сделать это с помощью
это убило
cmd.exe
и программу, для которой я дал команду.(В Windows)
источник
Popen("TASKKILL /F /IM " + process_name)
если у вас его нет, вы можете получить его изcommand
параметра.Когда
shell=True
оболочка является дочерним процессом, а команды - его дочерними. Так что любойSIGTERM
илиSIGKILL
убьет оболочку, но не ее дочерние процессы, и я не помню хорошего способа сделать это. Лучший способ, который я могу придумать, это использоватьshell=False
, иначе, когда вы убьете родительский процесс оболочки, он оставит несуществующий процесс оболочки.источник
Ни один из этих ответов не работал для меня, поэтому я оставляю код, который работал. В моем случае даже после завершения процесса
.kill()
и получения.poll()
кода возврата процесс не завершился.Следуя
subprocess.Popen
документации :В моем случае я пропустил
proc.communicate()
после звонкаproc.kill()
. Это очищает процесс stdin, stdout ... и завершает процесс.источник
Как сказал Сай, оболочка является дочерней, поэтому она перехватывает сигналы - лучший способ, который я нашел, - это использовать shell = False и использовать shlex для разделения командной строки:
Тогда p.kill () и p.terminate () должны работать так, как вы ожидаете.
источник
cwd
аргументPopen
.что я чувствую, что мы могли бы использовать:
это не убьет всю вашу задачу, но процесс с p.pid
источник
Я знаю, что это старый вопрос, но это может помочь кому-то искать другой метод. Это то, что я использую в Windows, чтобы убить процессы, которые я вызвал.
/ IM - это имя изображения, вы также можете сделать / PID, если хотите. / T убивает процесс, а также дочерние процессы. / F сила прекращает его. Си, как я установил, это то, как вы делаете это, не показывая окно CMD. Этот код используется в Python 3.
источник
Отправить сигнал всем процессам в группе
источник
Я не видел здесь упомянутого, поэтому я помещаю это на случай, если кому-то это нужно. Если все, что вы хотите сделать, это убедиться, что ваш подпроцесс завершается успешно, вы можете поместить его в менеджер контекста. Например, я хотел, чтобы мой стандартный принтер распечатывал изображение и с помощью диспетчера контекста гарантировал, что подпроцесс завершился.
Я считаю, что этот метод также кроссплатформенный.
источник
shell=True
помощью вопроса? Которого нет в вашем коде.thread.join()
. Надеюсь, это прояснит это.