線程(Thread)基本用法
一.線程的調用
1.無參
def run_01(): for i in range(6, 10): print("test01", i) time.sleep(1) th_01 = threading.Thread(target=run_01) # 創建線程 th_01.start() # 啟動線程 for i in range(0, 5): print("main", i) time.sleep(1)
threading中最主要的類就是Thread,我們可通過實例化Thread類來創建一個子線程,target參數為運行的事件。
start()方法為啟動線程,線程運行結束或報異常時自動會結束線程。
程序默認在主線程上運行,不做任何操作的話,子線程和主線程是同步進行的。
2.有參
def run_01(a): for i in range(6, 10): print("test01", i) time.sleep(1) th_01 = threading.Thread(target=run_01, args=("test",)) # 創建線程 th_01.start() # 啟動線程
若運行的事件有參數時,我們可通過args傳入一個元組入參,也可通過kwargs傳入字典類型。
def run_01(a): for i in range(6, 10): print("test01", i) time.sleep(1) th_01 = threading.Thread(target=run_01, kwargs={"a": "test"}) # 創建線程 th_01.start() # 啟動線程
key值要與參數值保持一致。
3.多參
def run_01(a, b): for i in range(6, 10): print("test01", i) time.sleep(1) th_01 = threading.Thread(target=run_01, args=(1, 2)) # 創建線程 # or # th_01 = threading.Thread(target=run_01, kwargs={"a": "test", "b": 1}) # 創建線程 th_01.start() # 啟動線程
和單個入參差不多,多傳入一個參數即可。
二.設置線程名稱,獲取線程狀態
1.子線程名稱默認是Thread-1,Thread-2…..,我們可通過Thread類中name屬性設置線程名,
def run(): for i in range(0, 5): print(i) thread = threading.Thread(target=run, name='test') # name設置線程名 print(thread.name, thread.getName()) # name,getname()方法獲取線程名
通過name屬性和getName()方法獲取線程名。修改/設備線程名也可通過setName()方法設置。
thread = threading.Thread(target=run, name='test') # name設置線程名 thread.setName("updateThreadName") print(thread.name, thread.getName()) # name,getName()方法獲取線程名
2.is_alive()為獲取線程當前的運行狀態
def run(): for i in range(0, 5): print(i) thread = threading.Thread(target=run, name='test') # name設置線程名 thread.start() bol = thread.is_alive() # 為true時表示正在運行,為false時停止運行 print(bol)
三.主/子線程執行順序
1.默認情況下主/子線程會同時執行,主線程會等待子線程結束後再結束。
def run(): for i in range(0, 5): print("thread", i) time.sleep(2) if __name__ == '__main__': thread = threading.Thread(target=run) thread.start() for i in range(5, 10): print("main", i) time.sleep(1)
2.Thread類中有個daemon屬性可控制執行結果
if __name__ == '__main__': thread = threading.Thread(target=run,daemon=True) thread.start() for i in range(5, 10): print("main", i) time.sleep(1)
創建子線程時我們將daemon設置為True,可以看出主線程結束後子線程也會結束運行,
不會等待子線程結束後再結束。也可通過setDaemon()方法設置。
if __name__ == '__main__': thread = threading.Thread(target=run) thread.setDaemon(True) thread.start() for i in range(5, 10): print("main", i) time.sleep(1)
四.join()用法
1.join()為堵塞主線程執行,優先執行子線程,等子線程執行完後再去執行主線程。
def run(): for i in range(0, 5): print("thread1", i) time.sleep(1) def run2(): for i in range(0, 5): print("thread2", i) time.sleep(1) if __name__ == '__main__': thread = threading.Thread(target=run) thread2 = threading.Thread(target=run2) thread.start() thread.join() # 開始堵塞主線程,只執行thread線程 thread2.start() for i in range(5, 10): print("main", i) time.sleep(1)
2.join(timeout=None)中timeout參數
timeout默認為None,可傳遞秒數,設置堵塞主線程的時間,timeout秒後不管子線程有沒有運行完都會執行主線程。
thread.join(timeout=2.0)
五.Event()方法的使用
我們都知道一個進程有多個線程,多個線程之間的資源是共享的,那麼如果多個線程去修改同
一個資源數據,就會出現數據錯亂的情況。Event類可以去堵塞線程的運行,我們先來看下Event()的幾個方法。
1.實例化Event()類
event = threading.Event()
Event()中有個_flag的私有屬性,默認為false,表示堵塞
2.wait()調用後表示開始堵塞
event.wait(timeout=2.0) # 調用該方法後,該線程會被堵塞,timeout為堵塞時間
3.set()方法設置flag為true,表示結束堵塞
event.set() # 設置self._flag = True
4.清除設置,flag值恢復false,繼續堵塞
event.clear() # self._flag = False
5.is_set()查看flag的值
print(event.is_set()) # 查看當前_flag的值
6.實例
import threading import time def run(event): print("當前flag的值", event.is_set()) event.wait() # 開始堵塞 for i in range(1, 6): print(i) time.sleep(1) if event.is_set() == False: break event = threading.Event() # self._flag = False thread = threading.Thread(target=run, args=(event,)) thread.start() print("\n開始堵塞2s") time.sleep(2) event.set() # 設置self._flag = True print("結束堵塞,運行2s") time.sleep(2) print("結束運行,跳出for循環") event.clear() # self._flag = False
解析:
上述中,子線程執行到event.wait()時就開始進行堵塞,主線程等待2s後調用set()方法使子線程繼續運行,
子線程循環兩次後主線程調用clear()設置flag值為false,子線程if判斷跳出循環,運行結束。
文章來源://www.cnblogs.com/lihongtaoya/ ,請勿轉載