Python多線程中比time.sleep更好用的暫停方式
Python多線程比time.sleep更好用的暫停
在python代碼中,如果需要程序暫停一段時間,通常情況下使用的是time.sleep()方法。
示例代碼:
import time
print('...部分代碼...')
time.sleep(3)
print('...剩下的代碼...')運行結(jié)果:

在多線程中,還有另外一種方法,threading模塊中的Event。
示例代碼:
import threading
event = threading.Event()
print('...部分代碼...')
event.wait(3)
print('...剩下的代碼...')運行結(jié)果:

使用event()方法,首先先打印,然后等待3秒,再繼續(xù)執(zhí)行后面的程序。
以上看起來和time.sleep()方法類似
接下來看一些例子來展示event()的好處
示例代碼:
import threading
import time
class Checker(threading.Thread):
def __init__(self, event):
super().__init__()
self.event = event
def run(self) -> None:
while not self.event.is_set():
print("進行檢查某個任務(wù)狀態(tài)!")
time.sleep(50)
# 某個異步任務(wù)
# async_task()
event = threading.Event()
checker = Checker(event)
checker.start()
# 異步任務(wù)檢查
# if user_cancel_task():
# event.set()運行結(jié)果:

但是在某種情況下,如果主動取消任務(wù),就不需要等待,這個時候就需要結(jié)束Checker這個子線程了。
線程是不能從外面主動殺死的,只能讓它自己退出。當執(zhí)行event.set()后,子線程里面self.event.is_set()就會返回 False,于是這個循環(huán)就不會繼續(xù)執(zhí)行了。
可是,如果某一輪循環(huán)剛剛開始,我在主線程里面調(diào)用了event.set()。此時,子線程還在time.sleep中,那么子線程需要等待50秒才會退出。這是就可以體現(xiàn)出event()的好處了。使用self.event.wait(60)。
示例代碼:
import threading
class Checker(threading.Thread):
def __init__(self, event):
super().__init__()
self.event = event
def run(self) -> None:
while not self.event.is_set():
print("進行檢查某個任務(wù)狀態(tài)!")
self.event.wait(50)
# 某個異步任務(wù)
# async_task()
event = threading.Event()
checker = Checker(event)
checker.start()
# 異步任務(wù)檢查
# if user_cancel_task():
# event.set()運行結(jié)果:

即便self.event.wait(50)剛剛開始阻塞,只要我在主線程中執(zhí)行了event.set(),子線程里面的阻塞立刻就會結(jié)束。
于是子線程立刻就會結(jié)束。不需要再白白等待50秒。
并且,event.wait()這個函數(shù)在底層是使用 C 語言實現(xiàn)的,不受 GIL 鎖的干擾。
總結(jié)
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
Python之標點符號string.punctuation的使用
Python的string模塊提供了一個方便的屬性string.punctuation,其中包含所有ASCII標點符號字符,這使得在處理和識別字符串中的標點符號時非常有用,可以通過簡單的in關(guān)鍵字來檢測字符是否為標點2024-09-09

