2015-06-24 2 views
1

Я пишу процесс daemon в python3.4, который управляет 2-3 другими внешними процессами. Я стараюсь избегать GIL, просто разделяя работу, которую они делают. Эти другие процессы носят временный характер. Итак, что мне нужно:Создание и удаление процесса в python

Запустите процесс из интерпретатора python и сразу отделите его от того, который его начал. Я хочу, чтобы они были полностью изолированы без совместного использования stdout, stderr, stdin или других ресурсов. Я не хочу ждать выхода процесса, кода возврата, stdout, stderr или предоставлять данные через stdin.

Согласно документам, теперь рекомендуется подпроцесс. Это то, что я использую сейчас:

subprocess.Popen(["python3.4", daemonfile], env=env) 

Он работает, но:

  • когда процесс запущен, стандартный вывод и стандартный поток ошибок печатаются на одной и той же консоли был запущен главный демон. Я хочу, чтобы они были полностью отстранены.
  • с 'shell = True', интерпретатор python переходит в режим интерпретатора.
  • subprocess.Popen было рекомендовать в пользу os.spawn *** называет

Что такое лучший способ начать полный отдельный процесс (технически, даже не ребенок?) И она полностью отделена от родителя, чтобы они не делили ресурсы?

+0

В этом случае не стоит беспокоиться о GIL: каждый процесс CPython имеет свой собственный GIL. – jfs

+0

вам, вероятно, не нужен настоящий демон, но вот [пример реализации и описание (щелкните по ссылке pep)] (https://pypi.python.org/pypi/python-daemon/) – jfs

+0

неправильно используйте 'shell = True' вместе с аргументом списка. Сравните: 'sh -c 'python a.py'' vs.' sh -c' python 'a.py' (вы не хотите последнего). – jfs

ответ

0

Прежде всего, нет процесса, который полностью «отсоединен» от любого процесса, даже ядра ОС, кроме первого процесса. Вы могли бы обнаружить, что всегда есть один корневой процесс для всех других процессов.

Итак, нет никакого способа начать полный отдельный процесс, даже не ребенок.

Что вы можете сделать, это использовать модуль multiprocessing, чтобы избежать ограничения GIL, и это автономный процесс, который связывается с основным процессом через канал, поэтому они не используют одно и то же пространство памяти.

касается других вопросов:

  1. Вы можете изменить стандартный вывод и стандартный поток ошибок, как вам хочется, пока это дескриптором.

  2. вы можете отключить оболочки = True ... просто чтобы убедиться, что вы знаете, что оболочка = True

  3. подпроцесс лишь средство для выполнения что-то и получить его выход или ошибку. Делайте то, что рекомендуется. Если вам не нужен код выхода или выхода, просто проигнорируйте его и используйте subprocess.PIPE для замены stdout/stderr, тогда он ничего не напечатает на консоли.

Я не уверен, почему для вас так важно использовать автономный процесс, если только GIL не ограничивает производительность. Использование потоков вместо процессов также могло бы повысить производительность, поскольку контекст процесса переключения намного дороже, чем контекст потока. Если это просто некоторые операции ввода-вывода или простые задачи, использование потоков более удобно.

+0

Имеет смысл, что полностью отсоединенный невозможно. Мне нужно только проверить, что происходит, когда главный «узел» умирает, но я думаю, что он, скорее всего, перефразирует оболочку. Основная проблема заключалась в том, что вывод отдельного дочернего объекта все еще появлялся на консольном выходе демона, который его запускал, но это можно решить с помощью настроек stdout/stderr и входа в файл вместо него. – radialmind

+0

Если вы используете модуль «многопроцессор», дочерние процессы будут оставлены без изменений, если родительский процесс будет мертв. Это плохо, поскольку никто не знает, кто создал дочерний процесс и почему он все еще работает. Это как призрак – Wingzero

Смежные вопросы