python threading.thread

Thread 是threading模塊中最重要的類之一,可使用它來建立線程。有兩種方式來建立線程:一種是經過繼承Thread類,重寫它的run方法;另外一種是建立一個threading.Thread對象,在它的初始化函數(__init__)中將可調用對象做爲參數傳入。下面分別舉例說明。先來看看經過繼承threading.Thread類來建立線程的例子:html

在代碼中,咱們建立了一個Counter類,它繼承了threading.Thread。初始化函數接收兩個參數,一個是瑣對象,另外一個是線程的名稱。在Counter中,重寫了從父類繼承的run方法,run方法將一個全局變量逐一的增長10000。在接下來的代碼中,建立了五個Counter對象,分別調用其start方法。最後打印結果。這裏要說明一下run方法 和start方法: 它們都是從Thread繼承而來的,run()方法將在線程開啓後執行,能夠把相關的邏輯寫到run方法中(一般把run方法稱爲活動[Activity]。);start()方法用於啓動線程。python

再看看另一種建立線程的方法:git

在這段代碼中,咱們定義了方法doAdd,它將全局變量count 逐一的增長10000。而後建立了5個Thread對象,把函數對象doAdd 做爲參數傳給它的初始化函數,再調用Thread對象的start方法,線程啓動後將執行doAdd函數。這裏有必要介紹一下threading.Thread類的初始化函數原型:github

def __init__(self, group=None, target=None, name=None, args=(), kwargs={})dom

  •   參數group是預留的,用於未來擴展;
  •   參數target是一個可調用對象(也稱爲活動[activity]),在線程啓動後執行;
  •   參數name是線程的名字。默認值爲「Thread-N「,N是一個數字。
  •   參數args和kwargs分別表示調用target時的參數列表和關鍵字參數。

Thread類還定義瞭如下經常使用方法與屬性:ide

Thread.getName()

Thread.setName()

Thread.name

用於獲取和設置線程的名稱。函數

Thread.ident

獲取線程的標識符。線程標識符是一個非零整數,只有在調用了start()方法以後該屬性纔有效,不然它只返回None。ui

Thread.is_alive()

Thread.isAlive()

判斷線程是不是激活的(alive)。從調用start()方法啓動線程,到run()方法執行完畢或遇到未處理異常而中斷 這段時間內,線程是激活的。spa

Thread.join([timeout])

調用Thread.join將會使主調線程堵塞,直到被調用線程運行結束或超時。參數timeout是一個數值類型,表示超時時間,若是未提供該參數,那麼主調線程將一直堵塞到被調線程結束。下面舉個例子說明join()的使用:線程

 

threading.RLock和threading.Lock

在threading模塊中,定義兩種類型的瑣:threading.Lock和threading.RLock。它們之間有一點細微的區別,經過比較下面兩段代碼來講明:

 

這兩種瑣的主要區別是:RLock容許在同一線程中被屢次acquire。而Lock卻不容許這種狀況。注意:若是使用RLock,那麼acquire和release必須成對出現,即調用了n次acquire,必須調用n次的release才能真正釋放所佔用的瑣。

threading.Condition

能夠把Condiftion理解爲一把高級的瑣,它提供了比Lock, RLock更高級的功能,容許咱們可以控制複雜的線程同步問題。threadiong.Condition在內部維護一個瑣對象(默認是RLock),能夠在建立Condigtion對象的時候把瑣對象做爲參數傳入。Condition也提供了acquire, release方法,其含義與瑣的acquire, release方法一致,其實它只是簡單的調用內部瑣對象的對應的方法而已。Condition還提供了以下方法(特別要注意:這些方法只有在佔用瑣(acquire)以後才能調用,不然將會報RuntimeError異常。):

Condition.wait([timeout]):

wait方法釋放內部所佔用的瑣,同時線程被掛起,直至接收到通知被喚醒或超時(若是提供了timeout參數的話)。當線程被喚醒並從新佔有瑣的時候,程序纔會繼續執行下去。

Condition.notify():

喚醒一個掛起的線程(若是存在掛起的線程)。注意:notify()方法不會釋放所佔用的瑣。

Condition.notify_all()

Condition.notifyAll()

喚醒全部掛起的線程(若是存在掛起的線程)。注意:這些方法不會釋放所佔用的瑣。

如今寫個捉迷藏的遊戲來具體介紹threading.Condition的基本使用。假設這個遊戲由兩我的來玩,一個藏(Hider),一個找(Seeker)。遊戲的規則以下:1. 遊戲開始以後,Seeker先把本身眼睛蒙上,蒙上眼睛後,就通知Hider;2. Hider接收通知後開始找地方將本身藏起來,藏好以後,再通知Seeker能夠找了; 3. Seeker接收到通知以後,就開始找Hider。Hider和Seeker都是獨立的個體,在程序中用兩個獨立的線程來表示,在遊戲過程當中,二者之間的行爲有必定的時序關係,咱們經過Condition來控制這種時序關係。

 

threading.Event

Event實現與Condition相似的功能,不過比Condition簡單一點。它經過維護內部的標識符來實現線程間的同步問題。(threading.Event和.NET中的System.Threading.ManualResetEvent類實現一樣的功能。)

Event.wait([timeout])

堵塞線程,直到Event對象內部標識位被設爲True或超時(若是提供了參數timeout)。

Event.set()

將標識位設爲Ture

Event.clear()

將標識伴設爲False。

Event.isSet()

判斷標識位是否爲Ture。

下面使用Event來實現捉迷藏的遊戲(可能用Event來實現不是很形象)

 

threading.Timer

threading.Timer是threading.Thread的子類,能夠在指定時間間隔後執行某個操做。下面是Python手冊上提供的一個例子:

threading模塊中還有一些經常使用的方法沒有介紹:

threading.active_count()
threading.activeCount()

獲取當前活動的(alive)線程的個數。

threading.current_thread()
threading.currentThread()

獲取當前的線程對象(Thread object)。

threading.enumerate()

獲取當前全部活動線程的列表。

threading.settrace(func)

設置一個跟蹤函數,用於在run()執行以前被調用。

threading.setprofile(func)

設置一個跟蹤函數,用於在run()執行完畢以後調用。

threading模塊的內容不少,一篇文章很難寫全,更多關於threading模塊的信息,請查詢Python手冊 threading模塊。

相關文章
相關標籤/搜索