Python之实时调度任务


过了年就开始面临毕业了,毕业季是幸福的,但也是紧迫的。2月已过就开始着手策划毕业论文了,一直到现在,论文基本完成了,感觉过去的一个半月的时间,对自己过去2年在实验室所学又温习了一遍。书到用时方恨少,在实验室研究论文的那段日子费了不少精力,等到现在写论文再回头去回忆自己所看文献的时候,突然发现当时没有做个详细的论文研究笔记是一个严重的失误。于是,写论文的过程变成了读一遍文献写一小段,到论文完成,我发现我温故知新,在很多以前没有理解的部分上有了新的认识!
 
好了,上面是对我最近生活的一点概况。2月下旬,有人看到我在博客园的一片随笔,关于SmartAPI的,然后通过QQ联系我,让我帮忙写个小程序,用于实时的去获取API接口所提供的所有城市的天气状况,于是我在那一周,挤出点时间出来,花了约3天的时间写了一个小demo,初步有了一个成果,并且程序比较稳健。
 
今天我就其中的一个部分和大家一起分享。客户的需求是,每隔2个小时收集一次实况天气预报,所以我需要写一个简单的调配程序来完成这个任务,即需要一个守护进程去计时,在指定的时间间隔自动调用相关的程序完成数据收集的过程。
 
开发环境: Windows8.1 + Python2.7
 
好了,废话不多说,先上代码:
 
复制代码
import sched, time
from threading import Thread, Timer
import subprocess
import sys
 
s = sched.scheduler(time.time, time.sleep)
 
class Job(Thread):
    def __init__(self, loc):
        Thread.__init__(self)
        self.loc = loc
    
    def run(self):
        print_time()
        print '--------------- begin to get weather info ---------------'
        subprocess.call("forecast3d.exe " + self.loc)
        print '---------------  end to get weather info  ---------------'
 
def each_day_time(hour, min, sec, next_day):
    struct = time.localtime()
    if next_day == 0:
        day = struct.tm_mday + 1
    else:
        day = struct.tm_mday
    return time.mktime((struct.tm_year,struct.tm_mon,day,
    hour,min,sec,struct.tm_wday, struct.tm_yday,
    struct.tm_isdst))
 
def print_time():
    print "From print_time", time.ctime()
 
def do_somthing(loc):
    job = Job(loc) 
    job.start()
 
def echo_start_msg():
    print '**************** auto task begin running ****************'
    
def main(loc, istomorrow=1):
    print '-------------- scheduled task will run once every two hours --------------'
    s.enterabs(each_day_time(8, 0, 0, istomorrow), 1, echo_start_msg, ())
    s.run()
    while(True):
        Timer(0, do_somthing, (loc,)).start()
        time.sleep(3 * 60 * 60)
        
if __name__ == "__main__":
    if len(sys.argv) < 2:
        print 'Usage: taskSched location <istomorrow>'
        sys.exit()
    elif len(sys.argv) == 2:
        main(sys.argv[1])
    else:
        main(sys.argv[1], sys.argv[2])
复制代码
在Python中,标准库中提供了用于定时的执行某个任务的模块,即sched和Timer类。先说sched模块,准确的说,它是一个调度(延时处理机制),每次想要定时执行某任务都必须写入一个调度。 
使用步骤如下: 
(1)生成调度器:
 
s = sched.scheduler(time.time,time.sleep)
 
 
第一个参数是一个可以返回时间戳的函数,第二个参数可以在定时未到达之前阻塞。可以说sched模块设计者是“在下很大的一盘棋”,比如第一个函数可以是自定义的一个函数,不一定是时间戳,第二个也可以是阻塞socket等。
 
(2)加入调度事件 
其实有enter、enterabs等等,我们以enter为例子。
 
s.enter(x1,x2,x3,x4)
 
 
四个参数分别为:间隔事件、优先级(用于同时间到达的两个事件同时执行时定序)、被调用触发的函数,给他的参数(注意:一定要以tuple给如,如果只有一个参数就(xx,))。
 
(3)运行
 
s.run()
分析上面的程序,我们可以知道,我们得目的就是检测系统的时间,当系统时间到达早上8点这个临界点,程序触发。这样的目的就是为了方便程序在前一天晚上跑起来,在第二天的早上8点开始获取第一批数据。
 
那么,Timer模块的作用呢,说白了就是计时器,程序循环计时,每过一定的时间执行一次收集操作。
 
最近论文写作完成,下一步的工作是将调度程序写成Windows服务,开机自启动,更加方便!

评论关闭