Запуск полностью независимого процесса с Python
Я пытаюсь запустить полностью независимый процесс из python. Я не могу использовать что-то простое, например os.startfile, поскольку мне нужно передать аргументы. В настоящее время я использую subprocess.popen, который дает мне 90% пути.
args = ["some_exe.exe", "some_arg", "another_arg"]
subprocess.Popen(args, creationflags=DETACHED_PROCESS | CREATE_NEW_PROCESS_GROUP, stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE)
Использование popen с отдельными флагами создания и трудами для std * запускает новый процесс, который живет после смерти родительского процесса. Так что все хорошо. Проблема в том, что новый "дочерний" процесс по-прежнему содержит дескриптор phantom для родителя. Поэтому, если я пытаюсь удалить родительский exe (мой python script входит в exe через pyinstaller), msiexec жалуется, что родительский exe все еще используется.
Таким образом, цель состоит в том, чтобы создать совершенно независимый процесс для запуска "some_exe.exe", который не имеет дескриптора исходного процесса.
Примечание. Это для Windows XP и выше. Я развиваюсь на Win7.
Ответы
Ответ 1
Я думаю, что нашел ответ. Используя Popen
с close_fds = True
, я смог запустить процесс, который был независимым и без дескрипторов родительскому.
Для docs посмотрите здесь и найдите close_fds
.
Или, в Windows, если close_fds истинно, тогда никакие дескрипторы не будут унаследованы по детскому процессу. Обратите внимание: в Windows вы не можете установить close_fds к true, а также перенаправить стандартные дескрипторы, установив stdin, stdout или stderr.
Обратите внимание, что это решение работает только в Windows. Я понятия не имею о какой-либо системе * nix.
Ответ 2
Я нашел здесь здесь:
В окнах (win xp) родительский процесс не завершится, пока longtask.py не завершит свою работу. Это не то, что вы хотите в CGI- script. Проблема не специфична для Python, в сообществе PHP проблемы одинаковы.
Решение состоит в передаче DETACHED_PROCESS Флаг создания процесса в базовый CreateProcess в win API. Если вы установили pywin32, вы можете импортировать флаг из модуля win32process, иначе вы должны определить его самостоятельно:
DETACHED_PROCESS = 0x00000008
pid = subprocess.Popen([sys.executable, "longtask.py" ], creationflags = DETACHED_PROCESS).pid