Python循环定时服务功能(相似contrab)
Python实现的循环定时服务功能。类似于Linux下的contrab功能。主要通过定时器实现。
注:Python中的threading.timer是基于线程实现的。每次定时事件产生时。回调完响应函数后线程就结束。而Python中的线程是不能restart的,所以这样的循环定时功能必需要在每次定时响应完毕后再又一次启动还有一个定时事件。
#!/usr/bin/env python # -*- coding: utf-8 -*- # import subprocess from threading import Timer import time import os import sys if os.name == 'posix': def become_daemon(our_home_dir='.', out_log='/dev/null', err_log='/dev/null', umask=0o022): "Robustly turn into a UNIX daemon, running in our_home_dir." # First fork try: if os.fork() > 0: sys.exit(0) # kill off parent except OSError as e: sys.stderr.write("fork #1 failed: (%d) %s\n" % (e.errno, e.strerror)) sys.exit(1) os.setsid() os.chdir(our_home_dir) os.umask(umask) # Second fork try: if os.fork() > 0: os._exit(0) except OSError as e: sys.stderr.write("fork #2 failed: (%d) %s\n" % (e.errno, e.strerror)) os._exit(1) si = open('/dev/null', 'r') so = open(out_log, 'a+', 0) se = open(err_log, 'a+', 0) os.dup2(si.fileno(), sys.stdin.fileno()) os.dup2(so.fileno(), sys.stdout.fileno()) os.dup2(se.fileno(), sys.stderr.fileno()) # Set custom file descriptors so that they get proper buffering. sys.stdout, sys.stderr = so, se else: def become_daemon(our_home_dir='.', out_log=None, err_log=None, umask=0o022): """ If we're not running under a POSIX system, just simulate the daemon mode by doing redirections and directory changing. """ os.chdir(our_home_dir) os.umask(umask) sys.stdin.close() sys.stdout.close() sys.stderr.close() if err_log: sys.stderr = open(err_log, 'a', 0) else: sys.stderr = NullDevice() if out_log: sys.stdout = open(out_log, 'a', 0) else: sys.stdout = NullDevice() class NullDevice: "A writeable object that writes to nowhere -- like /dev/null." def write(self, s): pass def outputLog(sLog): print sLog def toLog(sLog): sInfo = time.strftime("%y%m%d %H:%M:%S") sInfo += sLog outputLog(sInfo) def Log_Info(sLog): toLog('Info\t' + sLog) def Log_Error(sLog): toLog('error\t' + sLog) def Log_Debug(sLog): toLog('debug\t' + sLog) class TimerRunner: ''' ''' nTimeScds = 2 #时间间隔 sCmd = 'calc' oTm = None @classmethod def becomeDaemonize(cls): become_daemon() @classmethod def RunCmd(cls): oSubPcs = subprocess.Popen(cls.sCmd, stdout=subprocess.PIPE, stderr = subprocess.PIPE) while True: nReturnCode = oSubPcs.poll() if 0 == nReturnCode: Log_Info(oSubPcs.stdout.read()) break elif 0 > nReturnCode: Log_Error(oSubPcs.stderr.read()) break @classmethod def timerFun(cls): Log_Info("go to timer fun") cls.initTimer() cls.oTm.start() #再次启动计时,放在runcmd函数前,保证时间的准确性 cls.RunCmd() Log_Info("exit timer fun") @classmethod def initTimer(cls): cls.oTm = Timer(cls.nTimeScds, cls.timerFun) @classmethod def run(cls): cls.initTimer() cls.timerFun() cls.becomeDaemonize() def main(): TimerRunner.run()