Как запустить процесс демона из python в windows?

может ли мой скрипт python порождать процесс, который будет работать бесконечно?

Я не слишком хорошо знаком с python, ни с нерестилищем deamons, поэтому я кулачок с этим:

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 ответов


С помощью ответ Янне Karila отметил это, как вы можете запустить процесс, который не умирает, когда его родитель умирает, не нужно использовать win32process модуль.

DETACHED_PROCESS = 8
subprocess.Popen(executable, creationflags=DETACHED_PROCESS, close_fds=True)

DETACHED_PROCESS это Флаг Создания Процесса это передается в базовый является CreateProcess


этот вопрос был задан 3 года назад, и хотя основные детали ответа не изменились, учитывая его распространенность в поиске "Windows Python daemon", я подумал, что было бы полезно добавить некоторые обсуждения в интересах будущих Google arrivees.

есть две части вопроса:

  1. может ли скрипт Python порождать независимый процесс, который будет работать бесконечно?
  2. может ли скрипт 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 лучше объяснить в другом месте, но подводя итог:

  1. закрыть открытые файловые дескрипторы (как правило, все, но некоторым приложениям может потребоваться защитить некоторые дескрипторы от закрытия)
  2. измените рабочий каталог для процесса в подходящее место, чтобы предотвратить ошибки "каталог занят"
  3. изменить маску создания доступа к файлу (os.umask в мире Python)
  4. переместить приложение в фоновом режиме и сделать его отгородиться от возбуждения процесс
  5. полностью развестись с терминалом, включая перенаправление STDIN, STDOUT и STDERR в разные потоки (часто DEVNULL), и предотвратите reacquisition контролируя терминала
  6. обрабатывать сигналы, в частности, SIGTERM.

реальность ситуации заключается в том, что Windows, как операционная система, действительно не поддерживает понятие демона: приложения, которые начинаются с терминала (или в любом другом интерактивном контексте, включая запуск из Проводника и т. д.) будет продолжать работать с видимым окном, если управляющее приложение (в этом примере Python) не включило графический интерфейс без окон. Кроме того, обработка сигналов Windows прискорбно неадекватна и пытается отправить сигналы в независимая процесс Python (в отличие от подпроцесса, который не пережил бы закрытие терминала) почти всегда приведет к немедленному выходу этого процесса Python без какой-либо очистки (нет finally:, нет atexit, нет __del__ и т. д.).

свертывание вашего приложения в службу Windows, хотя во многих случаях жизнеспособная альтернатива, также не совсем подходит. То же самое верно для использования pythonw.exe (a безоконная версия Python который поставляется со всеми последними двоичными файлами Windows Python). В частности, они не могут улучшить ситуацию для обработки сигналов, и они не могут легко запустить приложение с терминала и взаимодействовать с ним во время запуска (для например, чтобы доставить динамические аргументы запуска в ваш скрипт, скажем, пароль, путь к файлу и т. д.),до "daemonizing". Кроме того, службы Windows требуют установки, которая-хотя это вполне возможно сделать быстро во время выполнения при первом вызове вашего "демона" - изменяет систему пользователя (реестр и т. д.), Что было бы весьма неожиданным, если вы пришли из мира Unix.

в свете этого я бы сказал, что запуск pythonw.exe подпроцесс с использованием subprocess.CREATE_NEW_PROCESS_GROUP вероятно, ближайший эквивалент Windows для процесса Python для эмуляции традиционного демона Unix. однако это по-прежнему оставляет вам дополнительную проблему обработки сигналов и связи при запуске (не говоря уже о том, что делает ваш код зависимым от платформы, что всегда расстраивает).

что все, как говорится, для тех, кто сталкивается с этой проблемой в будущем, я свернул библиотека daemoniker это обертывает оба правильных Демонизации в Unix и выше стратегии. Он также реализует обработку сигналов (как для Unix, так и для Windows) и позволяет передавать объекты в процесс "демон" с помощью рассола. Лучше всего, у него есть кросс-платформенный 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. прочитайте все комментарии, это разрешит любые сомнения

Если вы действительно хотите узнать больше

сначала прочтите это

Что такое процесс демона или creating-a-daemon-The-python-way

обновление: Подпроцесс-это не правильный способ достичь такого рода вещей