Python基礎(四)--- Python多執行緒介紹,開啟執行緒的三種方式,time模組,join,Daemon,Lock、Rlock,事件機制,Timer
阿新 • • 發佈:2018-11-19
一、多執行緒介紹 --------------------------------------------------------- 1.threading用於提供執行緒相關的操作,執行緒是應用程式中工作的最小單元。 2.python當前版本的多執行緒庫沒有實現優先順序、執行緒組,執行緒也不能被停止、暫停、恢復、中斷。 3.threading模組提供的類: Thread, Lock, Rlock, Condition, [Bounded]Semaphore, Event, Timer, local。 4.threading 模組提供的常用方法: threading.currentThread(): 返回當前的執行緒變數。 threading.enumerate(): 返回一個包含正在執行的執行緒的list。正在執行指執行緒啟動後、結束前,不包括啟動前和終止後的執行緒。 threading.activeCount(): 返回正在執行的執行緒數量,與len(threading.enumerate())有相同的結果。 5.threading 模組提供的常量: threading.TIMEOUT_MAX 設定threading全域性超時時間。 二、開啟執行緒的三種方式 ------------------------------------------------ 1.[方式一:通過低階api建立] # -*- encoding=utf-8 -*- # 導包 import threading #高階執行緒介面 import time import _thread #低階執行緒介面 #定義函式 def hello(str1,str2): time.sleep(2) #獲取當前執行緒名稱 print("當前執行緒name:" + threading.currentThread().getName()) print("hello: " + str1 + ":" + str2) # # 開啟執行緒方式1 -- 低階介面方式 # try: # _thread.start_new(hello,('tom','cat')); # while 1: # pass; # except Exception as e : # print("發生異常:" + e) 2.[方式二:高階api建立] try: #定義執行緒 for i in (1,2,3): t = threading.Thread(target = hello, args = ('tom','cat')) #執行執行緒 t.start() except Exception as e : print("發生異常:" + e) 3.[方式三:通過類建立] try: # 定義執行緒類 class MyThread(threading.Thread): def __init__(self,arg1,arg2): super(MyThread, self).__init__() #注意:一定要顯式的呼叫父類的初始化函式。 self.arg1=arg1 self.arg2=arg2 def run(self): #定義每個執行緒要執行的函式 time.sleep(1) hello(self.arg1,self.arg2) # 開啟執行緒 t = MyThread("tom","cat") t.start() except Exception as e : print("發生異常:" + e) 三、time模組 -------------------------------------------------------- import time //提取秒,精確到微秒. cc = int(time.time() * 1000) #時間戳 轉換成毫秒. cc = time.ctime() #日期date print(cc) 四、引數 --------------------------------------------------------- 1.後臺執行緒 t = MyThread("tom","cat") t.setDaemon(True) #設定執行緒為後臺執行緒 2.阻塞執行緒join # join()阻塞當前上下文環境的執行緒,直到呼叫此方法的執行緒終止或到達指定的timeout, # 即使設定了setDeamon(True)主執行緒依然要等待子執行緒結束。 t = MyThread("tom","cat") t.join() 3.設定執行緒名稱 t = MyThread("tom","cat") t.setName("thread--10") 五、Lock、Rlock ---------------------------------------------------------- 1.由於執行緒之間隨機排程:某執行緒可能在執行n條後,CPU接著執行其他執行緒。為了多個執行緒同時操作一個記憶體中的資源時不產生混亂,我們使用鎖。 2.Lock(指令鎖)是可用的最低階的同步指令。Lock處於鎖定狀態時,不被特定的執行緒擁有。Lock包含兩種狀態——鎖定和非鎖定,以及兩個基本的方法。 可以認為Lock有一個鎖定池,當執行緒請求鎖定時,將執行緒至於池中,直到獲得鎖定後出池。池中的執行緒處於狀態圖中的同步阻塞狀態。 3.RLock(可重入鎖)是一個可以被同一個執行緒請求多次的同步指令。RLock使用了“擁有的執行緒”和“遞迴等級”的概念,處於鎖定狀態時,RLock被某個執行緒擁有。擁有RLock的執行緒可以再次呼叫acquire(),釋放鎖時需要呼叫release()相同次數。 可以認為RLock包含一個鎖定池和一個初始值為0的計數器,每次成功呼叫 acquire()/release(),計數器將+1/-1,為0時鎖處於未鎖定狀態。 4.簡言之:Lock屬於全域性,Rlock屬於執行緒。 構造方法: Lock(),Rlock(),推薦使用Rlock() 例項方法: acquire([timeout]): 嘗試獲得鎖定。使執行緒進入同步阻塞狀態。 release(): 釋放鎖。使用前執行緒必須已獲得鎖定,否則將丟擲異常。 5.買票問題分析 # 票池 tickets = 100; # 執行緒鎖 lk = threading.RLock(); # 取票方法 def getTicket(): # 呼叫acquire([timeout])時,執行緒將一直阻塞, # 直到獲得鎖定或者直到timeout秒後(timeout引數可選)。 # 返回是否獲得鎖。 lk.acquire(); global tickets tmp = 0; if tickets > 0 : tmp = tickets; tickets -= 1; else: tmp = 0; lk.release(); return tmp; # 返回剩餘票數 class Saler(threading.Thread): def run(self): while True: tick = getTicket(); if tick != 0 : print(self.getName() + ":" + str(tick)) else: return ; s1 = Saler() s2 = Saler() s1.start() s2.start() 六、事件機制 --------------------------------------------------------- 1.Event(事件)是最簡單的執行緒通訊機制之一:一個執行緒通知事件,其他執行緒等待事件。Event內建了一個初始為False的標誌,當呼叫set()時設為True,呼叫clear()時重置為 False。wait()將阻塞執行緒至等待阻塞狀態。 2.Event其實就是一個簡化版的 Condition。Event沒有鎖,無法使執行緒進入同步阻塞狀態。 3.構造方法: Event() 4.例項方法: isSet(): 當內建標誌為True時返回True。 set(): 將標誌設為True,並通知所有處於等待阻塞狀態的執行緒恢復執行狀態。 clear(): 將標誌設為False。 wait([timeout]): 如果標誌為True將立即返回,否則阻塞執行緒至等待阻塞狀態,等待其他執行緒呼叫set()。 5.演示 # 定義一個事件 event = threading.Event() def func(): # 等待事件,進入等待阻塞狀態 print(threading.currentThread().getName() + '執行緒等待event的執行...') event.wait() # 一直等待,直到收到event # 收到事件後進入執行狀態 print (threading.currentThread().getName() +'執行緒收到事件,開始執行執行緒...') t1 = threading.Thread(target = func) t2 = threading.Thread(target = func) t1.start() t2.start() time.sleep(2) # 傳送事件通知 print('主執行緒發起事件') event.set() ============結果==================== Thread-1執行緒等待event的執行... Thread-2執行緒等待event的執行... [wait 2s] 主執行緒發起事件 Thread-1執行緒收到事件,開始執行執行緒... Thread-2執行緒收到事件,開始執行執行緒... 七、Timer --------------------------------------------------------------- 1.Timer(定時器)是Thread的派生類,用於在指定時間後呼叫一個方法。 2.構造方法: Timer(interval, function, args=[], kwargs={}) interval: 指定的時間 function: 要執行的方法 args/kwargs: 方法的引數 3.例項方法: Timer從Thread派生,沒有增加例項方法。 4.演示 def func(): print('定時炸彈爆炸啦~') # 新建一個定時器,5秒後執行func方法 timer = threading.Timer(5,func); # 開始計時 timer.start()