Python在一个守护进程中运行具有不同定时器的两个函数

时间:2012-05-21 23:59:26

标签: python linux timer daemon runner

我在两个不同的脚本中使用template python daemon discussed here来启动两个单独的守护进程。我想将它们组合成一个具有一个锁文件等的守护程序脚本。但是,每个都有不同的循环计时器,一个在1分钟,另一个在5分钟。我从这开始:

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 个答案:

答案 0 :(得分:2)

我不完全明白你为什么要这样做,但这应该有效:

使run_Arun_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的GIL,只有一个线程会同时运行Python语句,所以如果它们同时弹出它们会运行得慢一点。如果您希望它们能够并行运行,您可以非常简单地将其切换为使用multiprocessing

这将导致一些“计时器漂移”,因为您正在使用sleep(如果您的守护程序是独立运行的话)。如果这很重要,你可以改用中断,或计算下一个五分钟的时间,而不是仅仅睡5分钟。

答案 1 :(得分: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