Эффективный демон Python - PullRequest
28 голосов
/ 09 января 2011

Мне было любопытно, как вы можете запустить скрипт Python в фоновом режиме, повторяя задачу каждые 60 секунд.Я знаю, что вы можете поместить что-то в фон, используя &, это эффективно для этого случая?

Я думал сделать цикл, подождать 60 секунд и загрузить его снова, но что-то не так в этом.1003 *

Ответы [ 3 ]

94 голосов
/ 04 декабря 2011

Вместо того, чтобы писать свой собственный демон, используйте вместо него python-daemon ! python-daemon реализует хорошо работающую спецификацию демона PEP 3143 , «Стандартная библиотека процессов демона».

Я включил пример кода, основанный на принятом ответе на этот вопрос, и, хотя код выглядит практически идентично, он имеет важное принципиальное отличие.Без python-daemon вам пришлось бы использовать &, чтобы поместить ваш процесс в фоновый режим, и nohup и не дать вашему процессу быть убитым при выходе из оболочки.Вместо этого он автоматически отсоединится от вашего терминала при запуске программы.

Например:

import daemon
import time

def do_something():
    while True:
        with open("/tmp/current_time.txt", "w") as f:
            f.write("The time is now " + time.ctime())
        time.sleep(5)

def run():
    with daemon.DaemonContext():
        do_something()

if __name__ == "__main__":
    run()

Чтобы запустить его:

python background_test.py

И обратите внимание на отсутствиеиз & здесь.

Кроме того, этот другой ответ на стеке подробно объясняет многие преимущества использования python-daemon .

8 голосов
/ 09 января 2011

Я думаю, что ваша идея в значительной степени именно то, что вы хотите. Например:

import time

def do_something():
    with open("/tmp/current_time.txt", "w") as f:
        f.write("The time is now " + time.ctime())

def run():
    while True:
        time.sleep(60)
        do_something()

if __name__ == "__main__":
    run()

Вызов time.sleep(60) переведет вашу программу в спящий режим на 60 секунд. По истечении этого времени ОС разбудит вашу программу и запустит функцию do_something(), а затем вернет ее в режим сна. Пока ваша программа спит, она ничего не делает очень эффективно. Это общий шаблон написания фоновых сервисов.

Чтобы действительно запустить это из командной строки, вы можете использовать &:

$ python background_test.py &

При этом все выходные данные скрипта будут отправляться на тот же терминал, с которого вы его запустили. Вы можете перенаправить вывод, чтобы избежать этого:

$ python background_test.py >stdout.txt 2>stderr.txt &
6 голосов
/ 09 января 2011

Использование & в оболочке, вероятно, самый простой способ, как описал Грег.

Если вы действительно хотите создать мощного демона, вам нужно обратиться к команде os.fork ().

Пример из Википедии :

#!/usr/bin/env python
# -*- coding: utf-8 -*-

import os, time

def createDaemon():
  """ 
      This function create a service/Daemon that will execute a det. task
  """

  try:
    # Store the Fork PID
    pid = os.fork()

    if pid > 0:
      print 'PID: %d' % pid
      os._exit(0)

  except OSError, error:
    print 'Unable to fork. Error: %d (%s)' % (error.errno, error.strerror)
    os._exit(1)

  doTask()

def doTask():
  """ 
      This function create a task that will be a daemon
  """

  # Open the file in write mode
  file = open('/tmp/tarefa.log', 'w')

  # Start the write
  while True:
    print >> file, time.ctime()
    file.flush()
    time.sleep(2)

  # Close the file
  file.close()

if __name__ == '__main__':

  # Create the Daemon
  createDaemon()

И тогда вы можете поместить любую нужную задачу в блок doTask().

Вам не нужно запускать это с помощью &, и это позволит вам настроить выполнение немного дальше.

...