Timer繼承子Thread類,是Thread的子類,也是線程類,具有線程的能力和特征。這個(gè)類用來(lái)定義多久執(zhí)行一個(gè)函數(shù)。
它的實(shí)例是能夠延遲執(zhí)行目標(biāo)函數(shù)的線程,在真正執(zhí)行目標(biāo)函數(shù)之前,都可以cancel它。
Timer源碼:
class Timer(Thread): def __init__(self, interval, function, args=None, kwargs=None): Thread.__init__(self) self.interval = interval self.function = function self.args = args if args is not None else [] self.kwargs = kwargs if kwargs is not None else {} self.finished = Event() def cancel(self): """Stop the timer if it hasn't finished yet.""" self.finished.set() def run(self): self.finished.wait(self.interval) if not self.finished.is_set(): self.function(*self.args, **self.kwargs) self.finished.set()
Timer類使用方法與Thread定義子線程一樣,interval傳入間隔時(shí)間,function傳入線程執(zhí)行的函數(shù),args和kwargs傳入函數(shù)的參數(shù)。
提前cancel:
import threading import time def add(x,y): print(x+y) t = threading.Timer(10,add,args=(4,5)) t.start() time.sleep(2) t.cancel() print("===end===")
運(yùn)行結(jié)果:
===end===
start方法執(zhí)行之后,Timer對(duì)象會(huì)處于等待狀態(tài),等待10秒之后會(huì)執(zhí)行add函數(shù)。同時(shí),在執(zhí)行add函數(shù)之前的等待階段,主線程使用了子線程的cancel方法,就會(huì)跳過(guò)執(zhí)行函數(shù)結(jié)束。
使用event 事件實(shí)現(xiàn)Timer計(jì)時(shí)器:
import threading import logging import time logging.basicConfig(level=logging.INFO) # class MyTimer(threading.Thread): class MyTimer: def __init__(self,interval,fn,args=None): self.interval = interval self.fn = fn self.args = args self.event = threading.Event() def start(self): threading.Thread(target=self.__do).start() def cancel(self): self.event.set() def __do(self): self.event.wait(self.interval) if not self.event.is_set(): self.fn(*self.args) def add(x,y): logging.warning(x+y) t = MyTimer(5,add,(4,5)) t.start() # time.sleep(2) # t.cancel()
運(yùn)行結(jié)果:
WARNING:root:9
Event事件,是線程間通信機(jī)制中最簡(jiǎn)單的實(shí)現(xiàn),使用一個(gè)內(nèi)部的標(biāo)記flag,通過(guò)flag的True或False的變化來(lái)進(jìn)行操作。
Event源碼:
class Event:
def __init__(self): self._cond = Condition(Lock()) self._flag = False def _reset_internal_locks(self): self._cond.__init__(Lock()) def is_set(self): return self._flag isSet = is_set def set(self): with self._cond: self._flag = True self._cond.notify_all() def clear(self): with self._cond: self._flag = False def wait(self, timeout=None): with self._cond: signaled = self._flag if not signaled: signaled = self._cond.wait(timeout) return signaled
Event 方法:
?set()??????????????????? flag設(shè)置為True
?clear()???????????????? flag設(shè)置為False
?is_set()??????????????? flag是否為True,返回布爾值
?wait(timeout=None)? 設(shè)置等待flag變?yōu)門rue的時(shí)長(zhǎng),None為無(wú)限等待。等到了返回True,未等到超時(shí)了就返回False。
舉例:
老板雇傭了一個(gè)工人,讓他生產(chǎn)杯子,老板一直等著工人,直到生產(chǎn)了10個(gè)杯子。
import threading import logging import time logging.basicConfig(level=logging.INFO) cups = [] event = threading.Event()#event對(duì)象 def boss(e:threading.Event): if e.wait(30):#最多等待30秒 logging.info('Good job.') def worker(n,e:threading.Event): while True: time.sleep(0.5) cups.append(1) logging.info('make 1') if len(cups) >=n: logging.info('I finished my job. {}'.format(len(cups))) e.set()#flag設(shè)置為True break b = threading.Thread(target=boss,name='boos',args=(event,)) w = threading.Thread(target=worker,args=(10,event)) w.start() b.start()
運(yùn)行結(jié)果:
INFO:root:make 1
INFO:root:make 1
INFO:root:make 1
INFO:root:make 1
INFO:root:make 1
INFO:root:make 1
INFO:root:make 1
INFO:root:make 1
INFO:root:make 1
INFO:root:make 1
INFO:root:I finished my job. 10
INFO:root:Good job.
老板和工人使用同一個(gè)Event對(duì)象的標(biāo)記flag。
老板wait()設(shè)置為最多等待30秒,等待flag變?yōu)門rue,工人在做夠10杯子時(shí),將flag設(shè)置為True,工人必須在30秒之內(nèi)沒(méi)有做好杯子。
wait的使用:
import threading import logging logging.basicConfig(level=logging.INFO) def do(event:threading.Event,interval:int): while not event.wait(interval): # not event.wait(1) = True logging.info('To do sth.') e = threading.Event() t = threading.Thread(target=do,args=(e,1)) t.start() e.wait(10) # 也可以使用time.sleep(10) e.set() print('Man Exit.')
運(yùn)行結(jié)果:
INFO:root:To do sth.
INFO:root:To do sth.
INFO:root:To do sth.
INFO:root:To do sth.
INFO:root:To do sth.
INFO:root:To do sth.
INFO:root:To do sth.
INFO:root:To do sth.
INFO:root:To do sth.
Man Exit.
wait與sleep的區(qū)別是:wait會(huì)主動(dòng)讓出時(shí)間片,其它線程可以被調(diào)度,而sleep會(huì)占用時(shí)間片不讓出。
小結(jié):
Timer定時(shí)器繼承自Thread類,也是線程類。它的作用是等待n秒鐘之后執(zhí)行某個(gè)目標(biāo)函數(shù),可以使用cancel提前取消。
Event事件是通過(guò)True和False維護(hù)一個(gè)flag標(biāo)記值,通過(guò)這個(gè)標(biāo)記的值來(lái)決定做某事,wait()方法可以設(shè)置最長(zhǎng)等待flag設(shè)置為Ture的時(shí)長(zhǎng),超時(shí)還未設(shè)置為True就返回False。
PS:下面看下python之定時(shí)器Timer
timer類
Timer(定時(shí)器)是Thread的派生類,用于在指定時(shí)間后調(diào)用一個(gè)方法。
構(gòu)造方法:
Timer(interval, function, args=[], kwargs={}) interval: 指定的時(shí)間 function: 要執(zhí)行的方法 args/kwargs: 方法的參數(shù)
實(shí)例方法:
Timer從Thread派生,沒(méi)有增加實(shí)例方法。
例子一:
# encoding: UTF-8 import threading def func(): print 'hello timer!' timer = threading.Timer(5, func) timer.start()
線程延遲5秒后執(zhí)行。
總結(jié)
以上所述是小編給大家介紹的詳解Python 多線程 Timer定時(shí)器/延遲執(zhí)行、Event事件,希望對(duì)大家有所幫助,如果大家有任何疑問(wèn)請(qǐng)給我留言,小編會(huì)及時(shí)回復(fù)大家的。在此也非常感謝大家對(duì)腳本之家網(wǎng)站的支持!
如果你覺(jué)得本文對(duì)你有幫助,歡迎轉(zhuǎn)載,煩請(qǐng)注明出處,謝謝!
更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號(hào)聯(lián)系: 360901061
您的支持是博主寫作最大的動(dòng)力,如果您喜歡我的文章,感覺(jué)我的文章對(duì)您有幫助,請(qǐng)用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點(diǎn)擊下面給點(diǎn)支持吧,站長(zhǎng)非常感激您!手機(jī)微信長(zhǎng)按不能支付解決辦法:請(qǐng)將微信支付二維碼保存到相冊(cè),切換到微信,然后點(diǎn)擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對(duì)您有幫助就好】元
