Запуск полностью независимого процесса с 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