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()