過了年就開始面臨畢業了,畢業季是幸福的,但也是緊迫的。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服務,開機自啟動,更加方便!