python:threading多執行緒模
- 2020 年 1 月 13 日
- 筆記
假設我們有一個公共數據x(也可以叫共享資源,臨界資源),然後跑10個執行緒都去訪問這變數並對這個變數進行修改的操作,那麼就得到意料之外的結果。
ps:以下程式碼來自《征服python-語言基礎於典型應用》
import threading # 導入threading模組 import time # 導入time模組 class mythread(threading.Thread): # 通過繼承創建類 def __init__(self,threadname): # 初始化方法 # 調用父類的初始化方法 threading.Thread.__init__(self,name = threadname) def run(self): # 重載run方法 global x # 使用global表明x為全局變數 for i in range(3): x = x + 1 time.sleep(2) # 調用sleep函數,讓執行緒休眠5秒 print x tl = [] # 定義列表 for i in range(10): t = mythread(str(i)) # 類實例化 tl.append(t) # 將類對象添加到列表中 x=0 # 將x賦值為0 for i in tl: i.start() # 依次運行執行緒 #######運行結果###### [root@localhost ~]# python syn.py 30 30 30 30 30 30 30 30 30 30
由於x是全局變數(共享資源),每個執行緒對x操作後就休眠了
在執行緒休眠的時候其他執行緒也都開始執行操作,
最終休眠5秒後x的值最終就被修改為30了
使用互斥鎖來保護公共資源。用互斥鎖來保證同一時刻只有一個執行緒訪問公共資源,實現簡單的同步
互斥鎖:threading.Lock
互斥鎖方法:acquire() 獲取鎖 release():釋放鎖
當有一個執行緒獲的鎖之後,這把鎖就會進入locke狀態(被鎖起來了),另外的執行緒試圖獲取鎖的時候就會變成同步阻塞狀態,
當擁有執行緒鎖的的執行緒調用鎖方法 release()之後就會釋放鎖,那麼鎖就會變成開鎖unlocked狀態,之後再從同步阻塞狀態的執行緒中選擇一個來獲得鎖
import threading # 導入threading模組 import time # 導入time模組 class mythread(threading.Thread): # 通過繼承創建類 def __init__(self,threadname): # 初始化方法 threading.Thread.__init__(self,name = threadname) def run(self): # 重載run方法 global x # 使用global表明x為全局變數 lock.acquire() # 調用lock的acquire方法 for i in range(3): x = x + 1 time.sleep(2) # 調用sleep函數,讓執行緒休眠5秒 print x lock.release() # 調用lock的release方法 lock = threading.Lock() # 類實例化 tl = [] # 定義列表 for i in range(10): t = mythread(str(i)) # 類實例化 tl.append(t) # 將類對象添加到列表中 x=0 # 將x賦值為0 for i in tl: i.start() # 依次運行執行緒 ######運行結果###### [root@localhost ~]# python syn.py 3 6 9 12 15 18 21 24 27 30
可重入鎖:threading.RLock()
方法和互斥鎖一樣。
假設一個鎖嵌套的情況:有個執行緒以及獲取到鎖和共享資源了,但是又需要一把鎖來獲取另外一個資源,那麼只要把程式碼裡面的:
lock = threading.Lock()
修改為:
lock = threading.RLock()