用sched來定時執行任務

2014-3-1閱讀6180 評論3 html

先說一下,time.sleep()來讓程序休眠叉叉秒,即運行到這個地方,程序將釋放CPU,過了預設的叉叉秒後,程序繼續運行。 python

看一個簡單的例子,我最喜歡以最原始簡單的例子來闡述一個東西。 編程

import time

for i in range(5):
    print i
    time.sleep(10)

這個程序的結果就是,每隔10s鍾輸出一下i變量的值。(這個例子彷佛不用解釋就能明白time.sleep()是如何工做的。

這個方法雖然簡單,可是隻能用來實現簡單的例子。(不過我以爲用這個方法也是行的,若是要求不是太苛刻) api



如今步入主題,來講一個更高級一些的sched方法來定時執行任務。 安全

import time
import sched

schedule = sched.scheduler ( time.time, time.sleep )

def func(string1,float1):
    print "now is",time.time()," | output=",string1,float1

print time.time()
schedule.enter(2,0,func,("test1",time.time()))
schedule.enter(2,0,func,("test1",time.time()))
schedule.enter(3,0,func,("test1",time.time()))
schedule.enter(4,0,func,("test1",time.time()))
schedule.run()
print time.time()
這個例子的輸出結果是:
1393645450.07
now is 1393645452.07  | output= test1 1393645450.07
now is 1393645452.07  | output= test1 1393645450.07
now is 1393645453.07  | output= test1 1393645450.07
now is 1393645454.07  | output= test1 1393645450.07
1393645454.07

首先說分析一下,schedule是一個對象,每次等於它後面的那個就好了, 多線程

schedule這個傢伙就像一個預存你要定時執行的任務們兒 的盒子。 schedule.enter就是把你要定時多少秒後執行的任務放到這個盒子裏去。而schedule.run就是這時候去run你盒子的全部任務,任務就在這個時刻後,依次相對於這個時刻點的多少秒後運行。若是沒有run,那但是不會讓盒子的任務被執行。 分佈式


爲何每一行輸出的最後一個時間數據都是同樣的(除了最後一行)?由於他們傳入函數的數據是當時運行schedule.enter的那個時間點,並不是是你定時運行的那個時刻。 函數

而輸出中「now is  什麼什麼」的那個時刻,是運行的func函數中的time.time(),因此表明的是實際運行那個任務的時刻,因此不是同樣的。 spa



接着,就具體說一下schedule.enter這個對象方法的具體api應用說明 .net

schedule是一個對象,名稱是其餘的都行,只要是這一號任務便可,別搞個字符串來.enter就好了。(這篇教程寫得仍是比較面向初學者,廢話挺多)

schedule.enter(delay, priority, action, arguments)

第一個參數是一個整數或者float,表明多少秒後執行這個action任務。

第二個參數priority是優先級,0表明優先級最高,1次之,2次次之…當兩個任務是預約在同一個時刻執行時,根據優先級決定誰先執行。

第三個參數就是你要執行的任務,能夠簡單的理解成你要執行的函數的函數名。

第四個參數是你要傳入的這個定時執行的action爲函數名的函數的參數,最好是用"()"括號來包起來,包起來確定是不會出錯的。其次,當你只傳入一個參數時,用括號包起來後,必定要記住再打上一個逗號。即:schedule.enter(delay, priority, action, (argument1,))             雖然看起來有有點怪,但必定要這樣,不然,會出現錯誤,好比你不打逗號,你傳入一個字符串,它會覺得你傳入的是一個個字符,且每一個字符的地位等於一個參數。總之切記,打上逗號,就安全了。不然會出問題的。 另外若是沒有參數要傳入,就直接傳入空括號便可,即:schedule.enter(delay, priority, action, () )




最後,來講個更高級的東西,

在多線程的環境裏,上面的sched方法搞出來這個schedule搞搞搞搞,會由於線程安全的問題從而存在限制,一個東西執行了,若是沒結束,另一個東西就要等。阻塞了。

而咱們能夠用多線程的方式,避免在一條通道上堵車。

即神器——threading.Timer類。例子以下:

import time
from threading import Timer

def print_time( enter_time ):
    print "now is", time.time() , "enter_the_box_time is", enter_time


print time.time()
Timer(5,  print_time, ( time.time(), )).start()
Timer(10, print_time, ( time.time(), )).start()
print time.time()
輸出結果以下:
>>> 1393660025.58
>>> 1393660025.58
>>> now is 1393660030.58 enter_the_box_time is 1393660025.58
>>> now is 1393660035.58 enter_the_box_time is 1393660025.58

Timer就自動執行了,不須要再放到盒子裏,而後一會兒.run一下,另外,也不須要分優先級,能夠同時處理喔,爲了顯示多線程同時處理的效果,能夠把上面的第二個Timer的第一個參數也改爲5,而後實驗一下輸出結果,以下:
>>> 1393660052.12
>>> 1393660052.12
>>> now isnow is 1393660057.12 enter_the_box_time is 1393660052.12
 1393660057.12 enter_the_box_time is 1393660052.12

由於是同時輸出,而屏幕只有一個,因此發生了混在一塊兒的這種有些混亂的局面,這充分說明了是同時輸出。威力好大吧。有個高中同位在美國讀博士,就是寫底層的科學家,像分佈式運算、以及利用顯卡的計算能力去運算,這種東西我不擅長,這哥們內功深厚啊,惋惜哥老矣,哥混的是景觀規劃設計界,多年沒有提刀編程了,感受枯藤老樹昏鴉了。想起這高中同位,歷歷在目,寫底層,內功深厚啊。老子的專業只有景觀三元論,原本挺進步的,後來就成了幽默。

最後說個網址,是sched的官方手冊,http://docs.python.org/2/library/sched.html

相關文章
相關標籤/搜索