Подтвердить что ты не робот

Эффективный демона Python

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

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

4b9b3361

Ответ 1

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

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 &

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

$ python background_test.py >stdout.txt 2>stderr.txt &

Ответ 2

Вместо того, чтобы писать свой собственный демон, используйте 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

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

Кроме того, fooobar.com/questions/9186/... подробно объясняет многие преимущества использования python-daemon.

Ответ 3

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

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

Пример из Wikipedia:

#!/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().

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