Python: использование popen-опроса в фоновом процессе
В фоновом режиме я запускаю длинный процесс (фактически другой скрипт python). Мне нужно знать, когда он закончится. Я обнаружил, что Popen.poll()
всегда возвращает 0 для фонового процесса. Есть ли другой способ сделать это?
p = subprocess.Popen("sleep 30 &", shell=True,
stdout=subprocess.PIPE, stderr=subprocess.PIPE)
a = p.poll()
print(a)
Выше кода никогда не печатает None
.
Ответы
Ответ 1
Вам не нужно использовать фоновые символы &
синтаксис оболочки, так как subprocess
запускает процесс в фоновом режиме
Просто запустите команду нормально, затем подождите, пока Popen.poll
not None
вернется.
import time
import subprocess
p = subprocess.Popen("sleep 30", shell=True)
# Better: p = subprocess.Popen(["sleep", "30"])
# Wait until process terminates
while p.poll() is None:
time.sleep(0.5)
# It done
print "Process ended, ret code:", p.returncode
Ответ 2
Вы не должны запускать свой скрипт с амперсандом в конце. Поскольку оболочка разворачивает ваш процесс и возвращает код выхода 0.
Ответ 3
Я думаю, вам нужны команды popen.wait()
или popen.communicate()
. Общение будет захватывать данные stdout
и stderr
которые вы ввели в PIPE
. Если другой элемент является скриптом Python, я бы избежал запуска shell=True
вызова, выполнив что-то вроде:
p = subprocess.Popen([python.call, "my", params, (go, here)], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
(stdout, stderr) = p.communicate()
print(stdout)
print(stderr)
Конечно, они держат основной поток и ждут завершения другого процесса, что может быть плохо. Если вы хотите заняться ожиданиями, вы можете просто обернуть исходный код в цикле. (Ваш исходный код напечатал "Нет" для меня, кстати)
Пример обертывания в решении цикла:
p = subprocess.Popen([python.call, "my", params, (go, here)], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
while p.poll() == None:
# We can do other things here while we wait
time.sleep(.5)
p.poll()
(results, errors) = p.communicate()
if errors == '':
return results
else:
raise My_Exception(errors)