這篇文章主要介紹了舉例詳解Python中threading模塊的幾個常用方法,threading模塊用來創建和操作線程,是Python學習當中的重要知識,需要的朋友可以參考下
threading.Thread
Thread 是threading模塊中最重要的類之一,可以使用它來創建線程。有兩種方式來創建線程:一種是通過繼承Thread類,重寫它的run方法;另一種是創建一個threading.Thread對象,在它的初始化函數(__init__)中將可調用對象作為參數傳入。下面分別舉例說明。先來看看通過繼承threading.Thread類來創建線程的例子:
?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 #coding=gbk import threading, time, random count = 0 class Counter(threading.Thread): def __init__(self, lock, threadName): '''@summary: 初始化對象。 @param lock: 瑣對象。 @param threadName: 線程名稱。 ''' super(Counter, self).__init__(name = threadName) #注意:一定要顯式的調用父類的初始 化函數。 self.lock = lock def run(self): '''@summary: 重寫父類run方法,在線程啟動後執行該方法內的代碼。 ''' global count self.lock.acquire() for i in xrange(10000): count = count + 1 self.lock.release() lock = threading.Lock() for i in range(5): Counter(lock, "thread-" + str(i)).start() time.sleep(2) #確保線程都執行完畢 print count在代碼中,我們創建了一個Counter類,它繼承了threading.Thread。初始化函數接收兩個參數,一個是瑣對象,另一個是線程的名稱。在Counter中,重寫了從父類繼承的run方法,run方法將一個全局變量逐一的增加10000。在接下來的代碼中,創建了五個Counter對象,分別調用其start方法。最後打印結果。這裡要說明一下run方法 和start方法: 它們都是從Thread繼承而來的,run()方法將在線程開啟後執行,可以把相關的邏輯寫到run方法中(通常把run方法稱為活動[Activity]。);start()方法用於啟動線程。
再看看另外一種創建線程的方法:
?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 import threading, time, random count = 0 lock = threading.Lock() def doAdd(): '''@summary: 將全局變量count 逐一的增加10000。 ''' global count, lock lock.acquire() for i in xrange(10000): count = count + 1 lock.release() for i in range(5): threading.Thread(target = doAdd, args = (), name = 'thread-' + str(i)).start() time.sleep(2) #確保線程都執行完畢 print count在這段代碼中,我們定義了方法doAdd,它將全局變量count 逐一的增加10000。然後創建了5個Thread對象,把函數對象doAdd 作為參數傳給它的初始化函數,再調用Thread對象的start方法,線程啟動後將執行doAdd函數。這裡有必要介紹一下threading.Thread類的初始化函數原型:
?
1 def __init__(self, group=None, target=None, name=None, args=(), kwargs={})參數group是預留的,用於將來擴展;
參數target是一個可調用對象(也稱為活動[activity]),在線程啟動後執行;
參數name是線程的名字。默認值為“Thread-N“,N是一個數字。
參數args和kwargs分別表示調用target時的參數列表和關鍵字參數。
Thread類還定義了以下常用方法與屬性:
?
1 2 3 Thread.getName() Thread.setName() Thread.name用於獲取和設置線程的名稱。
?
1 Thread.ident獲取線程的標識符。線程標識符是一個非零整數,只有在調用了start()方法之後該屬性才有效,否則它只返回None。
?
1 2 Thread.is_alive() Thread.isAlive()判斷線程是否是激活的(alive)。從調用start()方法啟動線程,到run()方法執行完畢或遇到未處理異常而中斷 這段時間內,線程是激活的。
?
1 Thread.join([timeout])調用Thread.join將會使主調線程堵塞,直到被調用線程運行結束或超時。參數timeout是一個數值類型,表示超時時間,如果未提供該參數,那麼主調線程將一直堵塞到被調線程結束。下面舉個例子說明join()的使用:
?
1 2 3 4 5 6 7 8 9 10 11 12 13 import threading, time def doWaiting(): print 'start waiting:', time.strftime('%H:%M:%S') time.sleep(3) print 'stop waiting', time.strftime('%H:%M:%S') thread1 = threading.Thread(target = doWaiting) thread1.start() time.sleep(1) #確保線程thread1已經啟動 print 'start join' thread1.join() #將一直堵塞,直到thread1運行結束。 print 'end join'threading.RLock和threading.Lock
在threading模塊中,定義兩種類型的瑣:threading.Lock和threading.RLock。它們之間有一點細微的區別,通過比較下面兩段代碼來說明:
?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 import threading lock = threading.Lock() #Lock對象 lock.acquire() lock.acquire() #產生了死瑣。 lock.release() lock.release() import threading rLock = threading.RLock() #RLock對象 rLock.acquire() rLock.acquire() #在同一線程內,程序不會堵塞。 rLock.release() rLock.release()這兩種瑣的主要區別是:RLock允許在同