Python多執行緒threading join和守護執行緒setDeamon原理詳解
阿新 • • 發佈:2020-03-19
同一程序下的多個執行緒共享記憶體資料,多個執行緒之間沒有主次關係,相互之間可以操作;cpu執行的都是執行緒,預設程式會開一個主執行緒;程序是程式以及和程式相關資源的集合;某些場景下我們可以使用多執行緒來達到提高程式執行效率的目的,下面就多執行緒的一些基礎知識做簡要說明
簡單的多執行緒
import threading,time def test1(x): time.sleep(5) print(x**x) #下面定義兩個執行緒呼叫test1這個函式,建立多執行緒使用如下語法,target後面跟函式名,args傳遞實參,實參需要以元組形式傳遞 start_time = time.time() t1 = threading.Thread(target=test1,args=(5,)) t2 = threading.Thread(target=test1,args=(6,)) #啟動多執行緒 t1.start() t2.start() end_time = time.time() total_time = end_time - start_time print("two Thread used %s time"%total_time) #由於使用多執行緒,t1 t2啟動以後並不會等待期執行完程式才繼續往後走,因為主程式就是主執行緒和t1 t2是並行執行的,主程式執行到此t1 t2並未執行完成 time.sleep(6) #多執行緒啟動數量比較多時可以使用for迴圈,多執行緒並行執行,列印的結果有可能不是按照啟動順序來列印的 for i in range(5): t3 = threading.Thread(target=test1,args=(i,)) t3.start() time.sleep(6)
主執行緒等待非主執行緒執行完畢才繼續執行 join方法
#有些情況主執行緒需要子執行緒執行完畢後,有可能是將資料處理完畢後才執行接下來的主執行緒的東西 start_time1 = time.time() tl = [] #將多執行緒的物件存起來,用於後面join方法 for i in range(5): t4 = threading.Thread(target=test1,)) t4.start() tl.append(t4) for t in tl: #將多執行緒併發join,參加join的子執行緒執行完畢後才繼續執行下面的主執行緒。 t.join() end_time1 = time.time() total_time1 = end_time1 - start_time1 print(total_time1) #此次執行時間大約就是5s
#如果多個子執行緒一些join一些沒有join主執行緒怎麼處理???部分子執行緒join主執行緒會等join時間最長的子執行緒結束後才繼續,未參與join的子執行緒仍然和主執行緒並行執行 t5 = threading.Thread(target=test1,)) t6 = threading.Thread(target=test1,)) t5.start() t6.start() t5_join_start_time = time.time() t5.join() time.sleep(10) t5_join_end_time = time.time() print("t5 join time is %s"%(t5_join_end_time - t5_join_start_time)) #實際耗時15s
守護執行緒 setDeamon
#守護程序,即主執行緒結束以後所有的其它執行緒也立即結束,不用等其它執行緒執行完畢;正常情況即使沒加join主執行緒執行完畢當其它執行緒未執行完畢程式也不會退出,必須等待所有執行緒執行完畢程式才結束,類似主程式在末尾有預設的join def test1(x): time.sleep(5) print("i an other Thread",x**x) for i in range(5): t = threading.Thread(target=test1,)) t.setDaemon(True) t.start() print("Main Thread is done") #整個程式結束,不會等待守護執行緒列印操作執行完畢就直接結束了
遞迴鎖 Rlock
#遞迴鎖,一個鎖裡面巢狀著鎖,如果不使用遞迴鎖會導致釋放鎖邏輯錯誤,整個程式就跑偏了;使用遞迴鎖後程序會維護一個加鎖 解鎖的資料結構,保證釋放鎖不會出問題 lock = threading.Lock() def test2(): lock.acquire() print("this is test2") lock.release() def test3(): lock.acquire() print("this is test3") lock.release() def test4(): lock.acquire() test2() print("this is test4") test3() lock.release() rlock_test = threading.Thread(target=test4) rlock_test.start() while threading.active_count() != 1: print("current thread count is",threading.active_count()) #整個程式一直在列印有兩個執行緒,非主執行緒的鎖嵌套出問題導致無法退出,整個程式卡死 time.sleep(1)
將lock = threading.Lock()修改為lock = threading.RLock()整個程式就能正常結束;正常結束的輸出如下
this is test2
this is test4
current thread count is 2
this is test3
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支援我們。