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()