深入學習python (六) 用sched來定時執行任務
先說一下,time.sleep()來讓程式休眠叉叉秒,即執行到這個地方,程式將釋放CPU,過了預設的叉叉秒後,程式繼續執行。
看一個簡單的例子,我最喜歡以最原始簡單的例子來闡述一個東西。
- import time
- for i in range(5):
- print i
- time.sleep(10)
這個程式的結果就是,每隔10s鍾輸出一下i變數的值。(這個例子似乎不用解釋就能明白time.sleep()是如何工作的。
這個方法雖然簡單,但是隻能用來實現簡單的例子。(不過我覺得用這個方法也是行的,如果要求不是太苛刻)
現在步入主題,來說一個更高階一些的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,
- schedule.enter(4,0,func,("test1",time.time()))
- schedule.run()
- print time.time()
- 1393645450.07
- now is1393645452.07 | output= test1 1393645450.07
- now is1393645452.07 | output= test1 1393645450.07
- now is1393645453.07 | output= test1 1393645450.07
- now is1393645454.07 | output= test1
- 1393645454.07
首先說分析一下,schedule是一個物件,每次等於它後面的那個就行了,
schedule這個傢伙就像一個預存你要定時執行的任務們兒 的盒子。 schedule.enter就是把你要定時多少秒後執行的任務放到這個盒子裡去。而schedule.run就是這時候去run你盒子的所有任務,任務就在這個時刻後,依次相對於這個時刻點的多少秒後執行。如果沒有run,那可是不會讓盒子的任務被執行。
為什麼每一行輸出的最後一個時間資料都是一樣的(除了最後一行)?因為他們傳入函式的資料是當時執行schedule.enter的那個時間點,並非是你定時執行的那個時刻。
而輸出中“now is 什麼什麼”的那個時刻,是執行的func函式中的time.time(),所以代表的是實際執行那個任務的時刻,所以不是一樣的。
接著,就具體說一下schedule.enter這個物件方法的具體api應用說明
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 is1393660030.58 enter_the_box_time is1393660025.58
- >>> now is1393660035.58 enter_the_box_time is1393660025.58
Timer就自動執行了,不需要再放到盒子裡,然後一下子.run一下,另外,也不需要分優先順序,可以同時處理喔,為了顯示多執行緒同時處理的效果,可以把上面的第二個Timer的第一個引數也改成5,然後實驗一下輸出結果,如下:
- >>> 1393660052.12
- >>> 1393660052.12
- >>> now isnow is1393660057.12 enter_the_box_time is1393660052.12
- 1393660057.12 enter_the_box_time is1393660052.12
因為是同時輸出,而螢幕只有一個,所以發生了混在一起的這種有些混亂的局面,這充分說明了是同時輸出。威力好大吧。有個高中同位在美國讀博士,就是寫底層的科學家,像分散式運算、以及利用顯示卡的計算能力去運算,這種東西我不擅長,這哥們內功深厚啊,可惜哥老矣,哥混的是景觀規劃設計界,多年沒有提刀程式設計了,感覺枯藤老樹昏鴉了。想起這高中同位,歷歷在目,寫底層,內功深厚啊。老子的專業只有景觀三元論,本來挺進步的,後來就成了幽默。