1. 程式人生 > >深入學習python (六) 用sched來定時執行任務

深入學習python (六) 用sched來定時執行任務

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

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

  1. import time  
  2. for i in range(5):  
  3.     print i  
  4.     time.sleep(10)  

這個程式的結果就是,每隔10s鍾輸出一下i變數的值。(這個例子似乎不用解釋就能明白time.sleep()是如何工作的。

這個方法雖然簡單,但是隻能用來實現簡單的例子。(不過我覺得用這個方法也是行的,如果要求不是太苛刻)

現在步入主題,來說一個更高階一些的sched方法來定時執行任務。

  1. import time  
  2. import sched  
  3. schedule = sched.scheduler ( time.time, time.sleep )  
  4. def func(string1,float1):  
  5.     print"now is",time.time()," | output=",string1,float1  
  6. print time.time()  
  7. schedule.enter(2,0,func,("test1",time.time()))  
  8. schedule.enter(2,0,func,("test1",time.time()))  
  9. schedule.enter(3,
    0,func,("test1",time.time()))  
  10. schedule.enter(4,0,func,("test1",time.time()))  
  11. schedule.run()  
  12. print time.time()  
這個例子的輸出結果是:
  1. 1393645450.07
  2. now is1393645452.07  | output= test1 1393645450.07
  3. now is1393645452.07  | output= test1 1393645450.07
  4. now is1393645453.07  | output= test1 1393645450.07
  5. now is1393645454.07  | output= test1 
    1393645450.07
  6. 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類。例子如下:

  1. import time  
  2. from threading import Timer  
  3. def print_time( enter_time ):  
  4.     print"now is", time.time() , "enter_the_box_time is", enter_time  
  5. print time.time()  
  6. Timer(5,  print_time, ( time.time(), )).start()  
  7. Timer(10, print_time, ( time.time(), )).start()  
  8. print time.time()  
輸出結果如下:
  1. >>> 1393660025.58
  2. >>> 1393660025.58
  3. >>> now is1393660030.58 enter_the_box_time is1393660025.58
  4. >>> now is1393660035.58 enter_the_box_time is1393660025.58

Timer就自動執行了,不需要再放到盒子裡,然後一下子.run一下,另外,也不需要分優先順序,可以同時處理喔,為了顯示多執行緒同時處理的效果,可以把上面的第二個Timer的第一個引數也改成5,然後實驗一下輸出結果,如下:
  1. >>> 1393660052.12
  2. >>> 1393660052.12
  3. >>> now isnow is1393660057.12 enter_the_box_time is1393660052.12
  4.  1393660057.12 enter_the_box_time is1393660052.12

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