2012-05-21 5 views
1

Я использую template python daemon discussed here в двух разных сценариях для запуска двух отдельных демонов. Я хотел бы объединить их в один сценарий демона, который имеет один файл блокировки и т. Д. Однако у каждого есть другой таймер цикла, один на 1 минуту, а другой - на 5 минут. Я начинаю с этим:Python запускает две функции с разными таймерами в одном демоне

import os 
import subprocess 
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/test.pid' 
     self.pidfile_timeout = 5 
    def run(self): 

     try: 
      while True: 

       print "hello!" 

       # set the sleep time for repeated action here: 
       time.sleep(1) 

     except Exception, e: 
      raise 


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

Очевидная вещь, чтобы сделать было бы создать еще один класс, но я хочу, чтобы основной материал, как PidFile оставаться постоянным.

+2

Keep константы в ' App' и сделать подкласс для каждого приложения –

ответ

2

Я не совсем понимаю, почему вы хотите это сделать, но это должно работать:

Сделать run_A и run_B функции, чтобы сделать две независимые вещи (явно не те имена), в том числе и снам скоро. Это не имеет большого значения, но имеет смысл иметь их вне класса App.

Затем сделайте run функцию, которая выглядит следующим образом:

def run(self): 
    threads = [ 
     threading.Thread(target=run_A), 
     threading.Thread(target=run_B) 
    ] 

    for thread in threads: 
     thread.start() 
    for thread in threads: 
     thread.join() 

Это будет порождать отдельный поток для каждого задания, которые затем идут на его веселом пути. Если у вас есть общие ресурсы между заданиями, вам придется беспокоиться о блокировке.

Это предполагает, что задания выполняются быстро и точное время не имеет большого значения; из-за того, что CPython's GIL, только один поток будет запускать операторы Python сразу, поэтому, если они появятся одновременно, они будут работать немного медленнее. Вы могли бы довольно тривиально переключить это, чтобы использовать multiprocessing, если вы хотите, чтобы они могли работать параллельно.

Это приведет к некоторому «дрейфу таймера», потому что вы используете sleep (как и ваши демоны, если они запускаются независимо). Если это имеет значение, вы можете использовать прерывания вместо этого или рассчитать время до следующего кратного пяти минут, а не просто спать пять минут.

0

Если вам не нужно выполнять более длительную задержку для выполнения точно по времени, вы можете использовать простой аккумулятор, чтобы отслеживать, сколько времени было использовано несколькими циклами более короткого действия. Код ниже, будет работать отлично, если LONG_DELAY - точное целое число, кратное SHORT_DELAY. Если это не кратно, тем дольше цикл будет по-прежнему выполнять с запрашиваемым периодом в среднем, но задержка может быть короче или длиннее до SHORT_DELAY на любом проходе:

SHORT_DELAY = 60 # 1 minute 
LONG_DELAY = 300 # 5 minutes 

accum = LONG_DELAY 

while True: 
    do_short_delay_action() 

    if accum >= LONG_DELAY: 
     do_long_delay_action() 
     accum -= LONG_DELAY 

    time.sleep(SHORT_DELAY) 
    accum += SHORT_DELAY