轉載來自:https://www.pynote.net/archives/1783
似乎python中的定時器是都是這樣的,設置一個延遲時間,當經過了這么多時間后,某個函數被調用;如果希望反復調用,就需要編程在被調用的函數中,再次實現這個延遲一段時間調用函數的代碼。tkinter窗口的after函數就是這樣,本文介紹的threading.Timer也是這樣的機制。
import time import threading def createTimer(): t = threading.Timer(2, repeat) t.start() def repeat(): print('Now:', time.strftime('%H:%M:%S',time.localtime())) createTimer() createTimer()
這段代碼的功能就是每2秒打印出當前的時間,即一個2秒的定時器。運行效果如下:
E:\py>python timer.py Now: 16:36:15 Now: 16:36:17 Now: 16:36:19 Now: 16:36:21 Now: 16:36:23 Now: 16:36:25 Now: 16:36:27
threading.Timer接口還有可以給函數傳遞任意參數,具體參考python官方頁面:https://docs.python.org/3/library/threading.html#timer-objects,還有個cancel函數,可以在定時器被觸發前,取消這個Timer。
threading.Timer創建的是一個線程!這個細節要注意,定時器基本上都是在線程中執行。
我以前在做C#的應用的時候,就思考過定時器的一個問題:如果定時器內的代碼執行時間超過了定時器的間隔,怎么辦?看來在python中,這個問題是不存在的,下一次定時器的計時開始,會在定時器代碼執行完后才開始。其它編程語言提供的定時器機制,不清楚是否是自動完成了這樣的機制,還是不管這個細節,允許定時器函數在程度上並行存在多個執行序列。
如果想更精確地控制定時器函數的觸發時間,就需要把下一次定時器觸發的代碼,放在定時器執行代碼最開始的地方,如下:
import time import threading def createTimer(): t = threading.Timer(2, repeat) t.start() def repeat(): createTimer() print('Now-1:', time.strftime('%H:%M:%S',time.localtime())) time.sleep(3) print('Now-2:', time.strftime('%H:%M:%S',time.localtime())) createTimer()
定時器repeat要執行至少3秒,但是2秒后,下一個定時器就會被觸發,這是允許的!上面這段代碼的執行效果如下:
E:\py>python timer.py Now-1: 16:46:12 Now-1: 16:46:14 Now-2: 16:46:15 Now-1: 16:46:16 Now-2: 16:46:17 Now-1: 16:46:18 Now-2: 16:46:19 Now-1: 16:46:20 Now-2: 16:46:21 Now-1: 16:46:22 Now-2: 16:46:23
從打印信息來分析,同時存在多個repeat函數的執行序列是沒問題的,這種情況下,還需要認真考慮定時器函數的可重入問題!
以上就是對threading.Timer使用的介紹,請注意兩種設置定時器循環計時開始的方法,以及他們的區別。