python中斷time.sleep一種更優(yōu)雅的方式:event.wait
場(chǎng)景描述
實(shí)現(xiàn)一個(gè)功能,啟動(dòng)一個(gè)線(xiàn)程,只要線(xiàn)程不中斷,就一直while true,間斷10s累加某個(gè)數(shù);
當(dāng)線(xiàn)程線(xiàn)程信號(hào)時(shí),while停止,線(xiàn)程退出。
1、方法一 time.sleep
import time from threading import Thread class AddTask(Thread): def __init__(self): super().__init__() self.sum_num = 0 self._button = True def run(self): print('Begin to add ...') while self._button: print('Sleep start...') time.sleep(10) print('Sleep end...') self.sum_num += 10 print(f"Finish add, sum:{self.sum_num}...") def stop(self): print('Stop task...') self._button = False def do_main_task(): print('Do main task...') time.sleep(15) print('Finish main task...') return True if __name__ == '__main__': add_task = AddTask() add_task.start() main_task_end = do_main_task() if main_task_end: add_task.stop() time.sleep(1) print(f"sum: {add_task.sum_num}")
執(zhí)行結(jié)果:
Begin to add ...Do main task...
Sleep start...
Sleep end...
Sleep start...
Finish main task...
Stop task...
sum: 10
Sleep end...
Finish add,sum: 20...
解釋一下這段代碼的意思。在主線(xiàn)程里面,我調(diào)用do_main_task()
觸發(fā)了一個(gè)任務(wù)。這個(gè)任務(wù)執(zhí)行會(huì)久一些(這里設(shè)定15s)。但是這個(gè)任務(wù)完成以后,會(huì)有個(gè)返回值,告訴我完成了。另外創(chuàng)建一個(gè) add_task 子線(xiàn)程,每10秒累加10。
但某些情況下,我不需要等待了,例如用戶(hù)主動(dòng)取消了任務(wù)。這個(gè)時(shí)候,我就想提前結(jié)束這個(gè) add_task 子線(xiàn)程。
通過(guò)執(zhí)行結(jié)果可以看出,當(dāng)執(zhí)行一次+10,等待10s后,又過(guò)了5秒,主線(xiàn)程do_main_task結(jié)束了,這時(shí)add_task線(xiàn)程還在累加的sleep(10)中沒(méi)有退出。主線(xiàn)程執(zhí)行結(jié)果已經(jīng)是sum=10,再過(guò)5秒后add_task線(xiàn)程才結(jié)束。
但是,線(xiàn)程是不能從外面主動(dòng)殺死的,只能讓它自己退出。
2、方法二 event.wait
應(yīng)用threading
模塊里面的Event
用法和sleep差不多:
import threading event = threading.Event() event.wait(5)
上述例子可以這樣實(shí)現(xiàn):
import time from threading import Thread from threading import Event class AddTask(Thread): def __init__(self): super().__init__() self.sum_num = 0 self.event = Event() def run(self): print('Begin to add ...') while not self.event.is_set(): print('Sleep start...') self.event.wait(10) print('Sleep end...') self.sum_num += 10 print(f"Finish add, sum:{self.sum_num}...") def stop(self): print('Stop task...') self.event.set() def do_main_task(): print('Do main task...') time.sleep(15) print('Finish main task...') return True if __name__ == '__main__': add_task = AddTask() add_task.start() main_task_end = do_main_task() if main_task_end: add_task.stop() time.sleep(1) print(f"sum: {add_task.sum_num}")
執(zhí)行結(jié)果:
Do main task...
Begin to add ...
Sleep start...
Sleep end...
Sleep start...
Finish main task...
Stop task...
Sleep end...
Finish add, sum:20...sum: 20
當(dāng)執(zhí)行event.set()
后,子線(xiàn)程里面self.event.is_set()
就會(huì)返回 False,于是這個(gè)循環(huán)就不會(huì)繼續(xù)執(zhí)行了。
即使self.event.wait(10)
剛剛開(kāi)始阻塞,只要我在主線(xiàn)程中執(zhí)行了event.set()
,子線(xiàn)程里面的阻塞立刻就會(huì)結(jié)束。
于是子線(xiàn)程立刻就會(huì)結(jié)束。不需要再白白等待10秒。
并且,event.wait()
這個(gè)函數(shù)在底層是使用 C 語(yǔ)言實(shí)現(xiàn)的,不受 GIL 鎖的干擾。
總結(jié)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
非常詳細(xì)的Django連接mysql數(shù)據(jù)庫(kù)步驟記錄
我的Mysql中已經(jīng)有了項(xiàng)目需要使用的相關(guān)數(shù)據(jù)庫(kù),現(xiàn)在需要通過(guò)django來(lái)獲取Mysql里的數(shù)據(jù)并使用,下面這篇文章主要給大家介紹了關(guān)于非常詳細(xì)的Django連接mysql數(shù)據(jù)庫(kù)步驟,需要的朋友可以參考下2022-10-10手把手教你利用opencv實(shí)現(xiàn)人臉識(shí)別功能(附源碼+文檔)
最近搞一個(gè)人臉識(shí)別的項(xiàng)目練練手,不得不感嘆opencv做人臉檢測(cè)實(shí)在是強(qiáng),這篇文章主要給大家介紹了關(guān)于利用opencv實(shí)現(xiàn)人臉識(shí)別功能的相關(guān)資料,并附上了源碼以及文檔,需要的朋友可以參考下2021-09-09Python使用matplotlib繪圖無(wú)法顯示中文問(wèn)題的解決方法
這篇文章主要介紹了Python使用matplotlib繪圖無(wú)法顯示中文問(wèn)題的解決方法,結(jié)合具體實(shí)例形式分析了Python使用matplotlib繪圖時(shí)出現(xiàn)中文亂碼的原因與相關(guān)解決方法,需要的朋友可以參考下2018-03-03python在ubuntu中的幾種安裝方法(小結(jié))
本篇文章主要介紹了python在ubuntu中的幾種安裝方法(小結(jié)),小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-12-12詳解在OpenCV中實(shí)現(xiàn)的圖像標(biāo)注技術(shù)
圖像標(biāo)注在計(jì)算機(jī)視覺(jué)中很重要,計(jì)算機(jī)視覺(jué)是一種技術(shù),它允許計(jì)算機(jī)從數(shù)字圖像或視頻中獲得高水平的理解力,并以人類(lèi)的方式觀(guān)察和解釋視覺(jué)信息,本文將重點(diǎn)討論在OpenCV的幫助下創(chuàng)建這些注釋?zhuān)信d趣的朋友一起看看吧2022-06-06Python使用smtp和pop簡(jiǎn)單收發(fā)郵件完整實(shí)例
這篇文章主要介紹了Python使用smtp和pop簡(jiǎn)單收發(fā)郵件完整實(shí)例,簡(jiǎn)單介紹了smtp和pop,然后分享了相關(guān)實(shí)例代碼,具有一定借鑒價(jià)值,需要的朋友可以參考下2018-01-01python 實(shí)現(xiàn)倒計(jì)時(shí)功能(gui界面)
這篇文章主要介紹了python 實(shí)現(xiàn)倒計(jì)時(shí)功能(gui界面),幫助大家更好的理解和使用python,感興趣的朋友可以了解下2020-11-11