пусть python запускается в фоновом режиме с помощью функции внутри кода [duplicate]

Вы можете использовать словари для этого. Словари - это хранилища ключей и ценностей.

>>> dct = {'x': 1, 'y': 2, 'z': 3}
>>> dct
{'y': 2, 'x': 1, 'z': 3}
>>> dct["y"]
2

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

>>> x = "spam"
>>> z = {x: "eggs"}
>>> z["spam"]
'eggs'

В тех случаях, когда вы думаете сделать что-то вроде

var1 = 'foo'
var2 = 'bar'
var3 = 'baz'
...

список может быть более подходящим, чем dict. Список представляет упорядоченную последовательность объектов с целыми индексами:

l = ['foo', 'bar', 'baz']
print(l[1])           # prints bar, because indices start at 0
l.append('potatoes')  # l is now ['foo', 'bar', 'baz', 'potatoes']

Для упорядоченных последовательностей списки удобнее, чем dict с целыми ключами, потому что списки поддерживают итерацию в порядке индекса, slicing , append и другие операции, которые потребуют неудобного управления ключами с помощью dict.

224
задан DavidM 23 January 2009 в 17:48
поделиться

15 ответов

  • 1
    Изменить. Поскольку я изначально разместил этот ответ, теперь доступна эталонная реализация PEP 3143: pypi.python.org/pypi/python-daemon – Jeff Bauer 28 January 2011 в 19:45
  • 2
    Пакет python-daemon упрощает задачу ... – Pankaj 17 April 2011 в 10:16
  • 3
    @CrazyCasta: версия Sander Marechal по-прежнему доступна на Wayback Machine – Jeff Bauer 25 February 2014 в 23:26
  • 4
    Нашел этот образец кода, и это было очень полезно. – blindsnowmobile 19 February 2015 в 04:20
  • 5
    Поскольку "python-daemon" модульная документация по-прежнему отсутствует (см. также много других вопросов SO) и довольно неясна (как правильно запустить / остановить демона из командной строки с этим модулем?), я изменил образец кода Sander Marechal, чтобы добавить метод quit(), который выполняется перед тем как демон будет остановлен. Вот он. – Basj 12 November 2016 в 11:30

Вот мой базовый демон Python «Howdy World», с которого я начинаю работать, когда я разрабатываю новое приложение-демон.

#!/usr/bin/python
import time
from daemon import runner

class App():
    def __init__(self):
        self.stdin_path = '/dev/null'
        self.stdout_path = '/dev/tty'
        self.stderr_path = '/dev/tty'
        self.pidfile_path =  '/tmp/foo.pid'
        self.pidfile_timeout = 5
    def run(self):
        while True:
            print("Howdy!  Gig'em!  Whoop!")
            time.sleep(10)

app = App()
daemon_runner = runner.DaemonRunner(app)
daemon_runner.do_action()

Обратите внимание, что вам понадобится библиотека python-daemon. Вы можете установить его на:

pip install python-daemon

Затем просто запустите его с помощью ./howdy.py start и остановите его с помощью ./howdy.py stop.

88
ответ дан abccd 22 August 2018 в 21:46
поделиться
  • 1
    Этот модуль daemon, который вы импортируете, не является стандартной частью Python (пока). Он должен быть установлен с pip install python-daemon или эквивалентным. – Nate 11 February 2012 в 01:50
  • 2
    Я установил python-daemon, как вы описали, но когда я пытаюсь запустить мое приложение (то же самое, что и ваши последние 3 строки), я получаю ImportError: не могу импортировать имя runner – Nostradamnit 25 February 2012 в 16:16
  • 3
    Вы можете проверить, правильно ли он установлен? $ dpkg -L python-daemon | Уровеньвыше /. – Dustin Kirkland 27 February 2012 в 04:55
  • 4
    Это предложение кажется устаревшим - по состоянию на сентябрь 2013 года, во всяком случае, python.org/dev/peps/pep-3143 не упоминает «бегун», которые могут быть импортированы. Это, конечно, объяснило бы наблюдение @ Nostradamnit. – offby1 4 September 2013 в 22:44
  • 5
    Это все еще отлично подходит для меня в сентябре 2013 года на Ubuntu 13.04, с установленными пакетами Python на складе, python2.7 и python-daemon. Однако с python3 я вижу ошибку, & quot; from daemon import runner ImportError: Нет модуля с именем 'daemon' & quot; – Dustin Kirkland 5 September 2013 в 17:19

После нескольких лет и многих попыток, теперь я понимаю, что есть лучший способ, чем начать, остановить, перезапустить демон прямо с Python: вместо этого используйте инструменты ОС!

Короче говоря, вместо выполнения python myapp start и python myapp stop, я делаю это, чтобы запустить приложение:

screen -S myapp python myapp.py    
CTRL+A, D to detach

или screen -dmS myapp python myapp.py до начать и отделить его в одной команде .

Затем:

screen -r myapp

снова подключиться к этому терминалу. После этого в терминале можно использовать CTRL + C, чтобы остановить его.

6
ответ дан Basj 22 August 2018 в 21:46
поделиться

Есть множество проблем, которые нужно заботиться, когда вы становитесь хорошим процессом демона :

  • предотвращают дампы ядра (многие демоны выполняются как root, а core дампы могут содержать конфиденциальную информацию).
  • корректно ведут себя внутри chroot gaol
  • . UID, GID, рабочий каталог, umask и другие параметры процесса соответственно для использования
  • relinquish повышенные привилегии suid, sgid
  • закрыть все дескрипторы открытых файлов, причем исключения в зависимости от варианта использования
  • ведут себя правильно, если они начинаются внутри уже снятого контекст, такой как init, inetd и т. д.
  • настроить обработчики сигналов для разумного поведения демона, а также с определенными обработчиками, определенными в прецеденте
  • , перенаправить стандарт потоки stdin, stdout, stderr, поскольку процесс демона больше не имеет управляющего терминала
  • обрабатывает ПИД-файл как кооперативную консультативную блокировку, которая представляет собой целую банку червей в само со многими противоречивыми, но действительными способами t o behave
  • позволяют надлежащую очистку, когда процесс завершается
  • , фактически становятся процессом демона, не приводя к зомби

Некоторые из них являются стандартными, как описано в канонической литературе Unix ( Advanced Programming in UNIX Environment , покойным У. Ричардом Стивенсом, Addison-Wesley, 1992). Другие, такие как перенаправление потока и PID-обработка файлов , являются обычным поведением, которое ожидали бы большинство демонов, но это менее стандартизировано.

Все они покрываются PEP 3143 «Стандартная библиотека процессов демона». Реализация ссылок python-daemon работает на Python 2.7 или новее, а Python 3.2 или более поздней.

154
ответ дан bignose 22 August 2018 в 21:46
поделиться
  • 1
    & Quot; Гаол & Quot; должен быть «тюрьмой». правильно? – Prof. Falken 22 December 2010 в 14:13
  • 2
    Это устаревшее правописание тюрьмы. (Устаревший здесь, по крайней мере, он может быть не в других местах) – Winston Ewert 9 January 2011 в 04:38
  • 3
    «Gaol» написано правильно, потому что именно так писал W. Richard Stevens :-) – bignose 22 February 2011 в 08:51
  • 4
    Гаоль - это английская вещь . Плакат из Австралии, так что это имеет смысл. – devin 26 November 2012 в 20:35
  • 5
    Любые планы по созданию дружественной версии py3k? – Tim Tisdall 12 March 2013 в 16:35

Альтернатива - создать нормальную, не-демонанизированную программу Python, а затем демонтировать ее извне с помощью supervisord . Это может сэкономить много головных болей и является * nix- и языковым переносом.

24
ответ дан Chris Johnson 22 August 2018 в 21:46
поделиться
  • 1
    Я думаю, что это лучший способ. Особенно, если вы хотите запустить несколько демонов в одной операционной системе. Не используйте код, повторное использование. – guettli 1 October 2013 в 09:59
  • 2
    Это упрощает множество проблем. Я написал настоящих демонов - они непросты. – Chris Johnson 1 October 2013 в 14:35
  • 3
    Лучший ответ здесь скрыт :) – kawing-chiu 14 September 2015 в 13:16
  • 4
    Это золото. Потратив часы на запуск python-daemon, это решение, которое работает для меня. Отличная документация и примеры заставили моего демона за несколько минут. – Nikhil Sahu 11 October 2016 в 12:40

Я изменил несколько строк в примере кода Sander Marechal (упомянутый @JeffBauer в принятом ответе ), чтобы добавить метод quit(), который выполняется до того, как демон остановлен. Это иногда очень полезно.

Вот он.

Примечание: я не использую модуль «python-daemon», потому что документация по-прежнему отсутствует (см. также много других вопросов SO) и довольно неясна (как правильно запустить / остановить демона из командной строки с помощью этого модуля?)

1
ответ дан Community 22 August 2018 в 21:46
поделиться

Эта функция преобразует приложение в демона:

import sys
import os

def daemonize():
    try:
        pid = os.fork()
        if pid > 0:
            # exit first parent
            sys.exit(0)
    except OSError as err:
        sys.stderr.write('_Fork #1 failed: {0}\n'.format(err))
        sys.exit(1)
    # decouple from parent environment
    os.chdir('/')
    os.setsid()
    os.umask(0)
    # do second fork
    try:
        pid = os.fork()
        if pid > 0:
            # exit from second parent
            sys.exit(0)
    except OSError as err:
        sys.stderr.write('_Fork #2 failed: {0}\n'.format(err))
        sys.exit(1)
    # redirect standard file descriptors
    sys.stdout.flush()
    sys.stderr.flush()
    si = open(os.devnull, 'r')
    so = open(os.devnull, 'w')
    se = open(os.devnull, 'w')
    os.dup2(si.fileno(), sys.stdin.fileno())
    os.dup2(so.fileno(), sys.stdout.fileno())
    os.dup2(se.fileno(), sys.stderr.fileno())
3
ответ дан Ivan Kolesnikov 22 August 2018 в 21:46
поделиться

Вероятно, не прямой ответ на вопрос, но systemd можно использовать для запуска вашего приложения в качестве демона. Вот пример:

[Unit]
Description=Python daemon
After=syslog.target
After=network.target

[Service]
Type=simple
User=<run as user>
Group=<run as group group>
ExecStart=/usr/bin/python <python script home>/script.py

# Give the script some time to startup
TimeoutSec=300

[Install]
WantedBy=multi-user.target

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

-Orby

12
ответ дан Luke Dupin 22 August 2018 в 21:46
поделиться
  • 1
    если systemd доступен в вашем env ..., это хороший вариант. – warfares 1 September 2016 в 18:04

Еще одна вещь, о которой нужно подумать о демонализации в python:

Если вы используете ведение журнала python и хотите продолжить использовать его после демонтизации, обязательно вызовите close() на обработчиках (в частности, обработчики файлов).

Если вы этого не сделаете, обработчик все еще может считать, что файлы открыты, а ваши сообщения просто исчезнут - другими словами, убедитесь, что регистратор знает, что его файлы закрыты!

Это предполагает, что когда вы демоннизируете, вы закрываете ВСЕ дескрипторы открытых файлов неразборчиво - вместо этого вы можете попытаться закрыть все, кроме файлов журнала (но обычно проще закрыть все, а затем снова открыть те, которые вы хотите).

2
ответ дан Matthew Wilcoxson 22 August 2018 в 21:46
поделиться
  • 1
    Считаете ли вы, что открытие нового обработчика журналов лучше, чем передача обработчика ведения журнала через демона с помощью параметра files_preserve DaemonContext? – HeyWatchThis 19 May 2014 в 17:49
  • 2
    Вы закрываете только регистратор, вы не создаете новый (он просто откроет его, когда ему это нужно). Но даже если это действительно легко сделать, возможно, лучше использовать DaemonContext, поскольку он, вероятно, выполняет некоторые другие умные вещи (при условии, что сохранение все еще допускает правильную демонанизацию). – Matthew Wilcoxson 21 May 2014 в 11:04

80% времени, когда люди говорят «демона», им нужен только сервер. Поскольку вопрос совершенно неясен в этом вопросе, трудно сказать, какова возможная область ответов. Так как сервер достаточно, начните там. Если фактический «демон» действительно необходим (это редко), прочитайте в nohup как способ демонстрации сервера.

До тех пор, пока фактический демон фактически не понадобится, просто напишите простой сервер.

Также посмотрите на реализацию WSGI reference .

Также посмотрите на Simple HTTP Server .

«Есть ли какие-то дополнительные вещи, которые нужно учитывать?» Да. Около миллиона вещей. Какой протокол? Сколько запросов? Как долго обслуживать каждый запрос? Как часто они прибудут? Будете ли вы использовать выделенный процесс? Потоки? Подпроцессы? Написание демона - большая работа.

-24
ответ дан S.Lott 22 August 2018 в 21:46
поделиться
  • 1
    Ни одна из этих библиотек даже не делает ни одного fork(), не говоря уже о двух. Они не имеют никакого отношения к демонализации. – Brandon Rhodes 22 October 2010 в 17:31
  • 2
    В операционных системах Unix процесс «демона», как и антенны, которые греки называли «демонами», - это тот, который «стоит в стороне». Вместо того, чтобы напрямую обслуживать одного пользователя через TTY этого пользователя, демон не принадлежит ни одному TTY, но может отвечать на запросы от многих пользователей в системе, или - как crond или syslogd - выполняет домашние службы для всей системы. Чтобы создать процесс демона, необходимо, по крайней мере, выполнить double- fork(), когда все дескрипторы файлов закрыты, так что он невосприимчив к сигналам всех управляющих терминалов, включая системную консоль. См. Ответ bignose. – Brandon Rhodes 6 September 2011 в 05:08
  • 3
    @S Lott - «сервер» описывает процесс (прослушивает входящие запросы, а не инициирует его собственные действия); «Демон» описывает процесс выполнения (без окна или управляющего терминала). SimpleHTTPServer на самом деле является сервером, но тот, который не знает, как его демонизировать (например, вы можете использовать Ctrl-C). nohup - это утилита для демонстрации наивного процесса, поэтому ваш nohupped сервер действительно и сервер daemon и , как вы утверждаете. Этот вопрос о переполнении стека по существу задавал вопрос: «Как я могу реализовать nohup в Python?» – Brandon Rhodes 7 September 2011 в 15:40
  • 4
    Да, но мое понимание вопроса OPs заключается в том, что он хочет сделать демонанизацию из своей программы python и не использовать что-то еще. – Noufal Ibrahim 7 September 2011 в 19:47
  • 5
    @S Lott - Тебе не должно быть впечатлено! Автор любого другого ответа знал, что означает «демон», поэтому моя способность интерпретировать этот вопрос вряд ли уникальна. :) И откуда у вас появилась идея, что я хочу, чтобы автор изобрел колесо? Я думаю, что nohup - прекрасный инструмент, и я удалю свой -1 голос, если вы просто переместите эту полезную идею в свой фактический ответ. На самом деле, если вы упомянете supervisord и как он также сохранит автора от необходимости ведения журнала, сценария начала-остановки и перезапускает дросселирование, тогда я вам даже сделаю +1. :) – Brandon Rhodes 8 September 2011 в 14:41

Боюсь, модуль демонов, упомянутый @Dustin, не работает для меня. Вместо этого я установил python-daemon и использовал следующий код:

# filename myDaemon.py
import sys
import daemon
sys.path.append('/home/ubuntu/samplemodule') # till __init__.py
from samplemodule import moduleclass 

with daemon.DaemonContext():
    moduleclass.do_running() # I have do_running() function and whatever I was doing in __main__() in module.py I copied in it.

Запуск легко

> python myDaemon.py

только для полноты здесь - содержимое каталога образцового модуля

>ls samplemodule
__init__.py __init__.pyc moduleclass.py

Содержимое moduleclass.py может быть

class moduleclass():
    ...

def do_running():
    m = moduleclass()
    # do whatever daemon is required to do.
3
ответ дан Somum 22 August 2018 в 21:46
поделиться

, поскольку python-daemon еще не поддерживает python 3.x, и из того, что можно прочитать в списке рассылки, он, возможно, никогда не будет, я написал новую реализацию PEP 3143: pep3143daemon

pep3143daemon должен поддерживать как минимум python 2.6, 2.7 и 3.x

Он также содержит класс PidFile.

Библиотека зависит только от стандартной библиотеки и на шести модулях.

Его можно использовать как замену для python-daemon.

Вот документация .

5
ответ дан stephan schultchen 22 August 2018 в 21:46
поделиться

Самый простой способ создания демона с Python - использовать фреймворк Twisted . Он обрабатывает все необходимое для демонализации. Он использует шаблон Reactor Pattern для обработки параллельных запросов.

-2
ответ дан Travis B. Hartwell 22 August 2018 в 21:46
поделиться
  • 1
    Это слишком большой молот для использования. Большинство людей просто хотят запустить короткий скрипт Python, который они написали как демон. python-daemon, как описано выше, является правильным ответом. – Tom Swirly 5 March 2012 в 23:59
  • 2
    Хотя этот ответ был довольно высокомерным, это было полезно. – fiatjaf 17 November 2012 в 15:36

Обратите внимание на пакет python-daemon , который решает множество проблем, стоящих за демонами.

Среди других функций он позволяет (из описания пакета Debian):

  • Отключите процесс в своей группе процессов.
  • Установите среду процесса, подходящую для работы внутри chroot.
  • Отказаться от прав suid и sgid.
  • Закройте все дескрипторы открытых файлов.
  • Измените рабочий каталог, uid, gid и umask.
  • Установите соответствующие обработчики сигналов.
  • Откройте новые файловые дескрипторы для stdin, stdout и stderr.
  • Управление указанным файлом блокировки PID.
  • Зарегистрировать функции очистки для обработки на выходе.
42
ответ дан Viliam 22 August 2018 в 21:46
поделиться
[g1] [g0] YapDi [/g0] является относительно новым модулем Python, который появился в Hacker News. Выглядит довольно полезно, может быть использовано для преобразования скрипта Python в режим демона изнутри скрипта. [/G1]
6
ответ дан Basj 5 November 2018 в 19:12
поделиться
Другие вопросы по тегам:

Похожие вопросы: