Как запустить процесс демона из Python на Windows?
Может ли мой скрипт на python создать процесс, который будет работать бесконечно?
Я не слишком знаком ни с питоном, ни с порождающими дэймонами, поэтому придумаю это:
si = subprocess.STARTUPINFO()
si.dwFlags = subprocess.CREATE_NEW_PROCESS_GROUP | subprocess.CREATE_NEW_CONSOLE
subprocess.Popen(executable, close_fds = True, startupinfo = si)
Процесс продолжает выполняться после python.exe, но закрывается, как только я закрываю окно cmd.
3 ответа
Используя ответ, Джанн Карила указал, что это то, как вы можете запустить процесс, который не умирает, когда умирает его родитель, нет необходимости использовать win32process
модуль.
DETACHED_PROCESS = 8
subprocess.Popen(executable, creationflags=DETACHED_PROCESS, close_fds=True)
DETACHED_PROCESS
является флагом создания процесса, который передается в базовую функцию CreateProcess.
Этот вопрос был задан 3 года назад, и хотя основные детали ответа не изменились, учитывая его распространенность в поисках "Демон Windows Python", я подумал, что было бы полезно добавить некоторые обсуждения для будущих пользователей Google.
На самом деле есть две части вопроса:
- Может ли скрипт Python создать независимый процесс, который будет работать бесконечно?
- Может ли скрипт Python действовать как демон Unix в системе Windows?
Ответ на первый однозначный да; как уже указывалось; с помощью subprocess.Popen
с creationflags=subprocess.CREATE_NEW_PROCESS_GROUP
ключевое слово будет достаточно:
import subprocess
independent_process = subprocess.Popen(
'python /path/to/file.py',
creationflags=subprocess.CREATE_NEW_PROCESS_GROUP
)
Обратите внимание, что, по крайней мере, по моему опыту, CREATE_NEW_CONSOLE
здесь не нужно
При этом поведение этой стратегии не совсем то, что вы ожидаете от демона Unix. Что представляет собой хорошо себя ведущий демон Unix, лучше объяснить в другом месте, но подведем итог:
- Закройте открытые дескрипторы файлов (как правило, все они, но некоторым приложениям может потребоваться защитить некоторые дескрипторы от закрытия)
- Измените рабочий каталог для процесса на подходящее место, чтобы предотвратить ошибки "Directory Busy"
- Изменить маску создания доступа к файлу (
os.umask
в мире питонов) - Переместите приложение в фоновый режим и отключите его от процесса инициации.
- Полностью развод с терминала, включая перенаправление
STDIN
,STDOUT
, а такжеSTDERR
в разные потоки (частоDEVNULL
) и предотвратить повторный захват управляющего терминала - Обрабатывать сигналы, в частности,
SIGTERM
,
Реальность ситуации такова, что Windows, как операционная система, действительно не поддерживает понятие демона: приложения, запускаемые с терминала (или в любом другом интерактивном контексте, включая запуск из Проводника и т. Д.), Будут продолжать работать с видимым окном, если только управляющее приложение (в данном примере Python) не имеет GUI без окон. Кроме того, обработка сигналов Windows крайне неадекватна, и попытки отправить сигналы независимому процессу Python (в отличие от подпроцесса, который не выдержит закрытия терминала) почти всегда приводят к немедленному завершению этого процесса Python без какой-либо очистки (нет finally:
нет atexit
нет __del__
, так далее).
Свернуть ваше приложение в службу Windows, хотя во многих случаях это жизнеспособная альтернатива, также не совсем подходит. То же самое относится и к использованию pythonw.exe
( версия Python без окон, которая поставляется со всеми последними двоичными файлами Windows Python). В частности, им не удается улучшить ситуацию с обработкой сигналов, и они не могут легко запустить приложение из терминала и взаимодействовать с ним во время запуска (например, для доставки аргументов динамического запуска в ваш скрипт, скажем, возможно, пароля, файла). путь и т. д.), перед "демонизацией". Кроме того, службы Windows требуют установки, которая, хотя и вполне возможна для быстрого выполнения во время выполнения при первом вызове "демона", изменяет систему пользователя (реестр и т. Д.), Что было бы весьма неожиданно, если вы пришли из мир Unix.
В свете этого я бы сказал, что запуск pythonw.exe
использование подпроцесса subprocess.CREATE_NEW_PROCESS_GROUP
вероятно, является ближайшим аналогом Windows для процесса Python, чтобы эмулировать традиционный демон Unix. Однако, это все еще оставляет вас с дополнительной проблемой обработки сигналов и запуска связи (не говоря уже о том, чтобы сделать ваш код зависимым от платформы, что всегда расстраивает).
Тем не менее, для любого, кто столкнется с этой проблемой в будущем, я развернул библиотеку под названием daemoniker, которая объединяет как правильную демонизацию Unix, так и вышеприведенную стратегию. Он также реализует обработку сигналов (как для систем Unix, так и для систем Windows) и позволяет передавать объекты процессу "демона" с помощью pickle. Лучше всего то, что он имеет кроссплатформенный API:
from daemoniker import Daemonizer
with Daemonizer() as (is_setup, daemonizer):
if is_setup:
# This code is run before daemonization.
do_things_here()
# We need to explicitly pass resources to the daemon; other variables
# may not be correct
is_parent, my_arg1, my_arg2 = daemonizer(
path_to_pid_file,
my_arg1,
my_arg2
)
if is_parent:
# Run code in the parent after daemonization
parent_only_code()
# We are now daemonized, and the parent just exited.
code_continues_here()
Для этого вы можете демонизировать ваш процесс Python или, если вы используете среду Windows, вы хотите запустить его как службу Windows.
Вы знаете, я люблю ненавидеть публиковать только веб-ссылки:
Но для получения дополнительной информации по вашему требованию:
Простой способ реализации службы Windows. прочитайте все комментарии, это разрешит любые сомнения
Если вы действительно хотите узнать больше
Сначала прочитайте это
что такое процесс демона или путь создания демона python
обновление: подпроцесс не является правильным способом для достижения такого рода вещи