Pythonは1つのデーモンで異なるタイマーを持つ2つの関数を実行します
質問
テンプレートPythonデーモン 2つの異なるスクリプトで、2つの別々のデーモンを起動します。ただし、1つのロックファイルなどを持つ1つのデーモンスクリプトにそれらを組み合わせたいと思います。私はこれから始めています:
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()
.
解決
私はこれをやりたい理由が完全に入手しませんが、これは機能するはずです:
run_A
とrun_B
関数は、睡眠などを含む2つの独立したもの(明らかにそれらの名前ではありません)を行うように機能します。それは本当に問題ではありませんが、これらは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 のために、1つのスレッドは一度にPythonステートメントを実行します。同じ時間が少し遅く実行されます。並行して実行できるようにしたい場合は、multiprocessing
を使用するように、これを非常に簡単に切り替えることができます。
これは、sleep
を使用しているため、 "Timer Drift"になります(デーモンが独立して実行されている場合はデーモンが使用するように)。これが重要な場合は、代わりに割り込みを使用することも、5分だけ眠っているのではなく5分の次の倍数までの時間を計算することができます。
他のヒント
長期遅延が正確に実行されることが不可欠でない場合は、単純なアキュムレータを使用して、短いアクションの数サイクルで使用された時間を追跡できます。以下のコードは、long_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
.