python線程threading.Timer源碼解讀


threading.Timer的作用

官方給的定義是

"""Call a function after a specified number of seconds:

t = Timer(30.0, f, args=None, kwargs=None)
t.start()
t.cancel() # stop the timer's action if it's still waiting

"""

意思是

  在一個特定的秒數之后調用一個函數,使用方法是創建一個Timer實例,然后start()啟動線程,如果在線程調用傳入的函數之前可以使用cancel進行取消。   

threading.Timer源碼分析   

 

 1 class Timer(Thread):  # 繼承自Thread類
 2     """Call a function after a specified number of seconds:
 3 
 4             t = Timer(30.0, f, args=None, kwargs=None)
 5             t.start()
 6             t.cancel()     # stop the timer's action if it's still waiting
 7 
 8     """   
 9 
10     def __init__(self, interval, function, args=None, kwargs=None):  # 初始化的時候傳參是延遲時間調用的函數函數的可變位置參數函數的可變關鍵字參數 11         Thread.__init__(self)  # 調用Thread類初始化配置實例
12         self.interval = interval  # 在使用Thread類初始化配置實例之后再額外的增加interval屬性
13         self.function = function  # 同理再額外的增加function屬性
14         self.args = args if args is not None else []   # 如果args不是空的話就使用args,如果是空就給一個空list
15         self.kwargs = kwargs if kwargs is not None else {}  # 同理,kwargs不是空的就是kwargs,如果是空就給一個空字典
16         self.finished = Event()  # 再添加一個屬性finished,是一個Event類的實例,這里知道Event類的實例用法就知道它在這里要怎么用了
17 
18     def cancel(self):
       """如果finished屬性還沒有被set,即函數function還沒有被調用的之前阻止,因為下面函數調用之前會判斷finished是否被set了,所以這里趕在調用之前注定set就能夠阻止后面的調用。"""
19 """Stop the timer if it hasn't finished yet.""" 20 self.finished.set() 21 22 def run(self): # 繼承自Thread類,並且重寫了Thread類,我們分析Thread類的源碼會發現,start()方法會主動調用self.run(),
              # 我們Timer類沒有實現start()方法,這樣Timer類實例在執行start()的時候會跑到父類Thread上,然后調用父類的start,
              # 在父類的start()方法中會有一句self.run()來調用工作線程中的函數,這里self是Timer的實例,所以,這里可以重寫run就可以設定run的時間了。
23 self.finished.wait(self.interval) # 這里使用Event類的實例的wait方法,等待了我們設定的self.interval時間,然后關鍵點是下面一句 24 if not self.finished.is_set(): # 這一句是關鍵點,檢查一下是否被set了,如果沒有被set了就調用傳入的函數,如果被set了有兩種情況:
                          # 第一種情況是在self.finished.wait(self.interval)的期間,我們調用cancel主動提前set了;
# 第二種情況是已經start()過一次了,這里就不能再進行start了這樣就和父類的保持了一致:即一個線程只能夠start一次
25 self.function(*self.args, **self.kwargs) 26 self.finished.set() # 調用完成后set,即便之前已經被set了,這里還可以被set,因為Event實例可以被set多次。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM