本文介紹了Python對于線程的支持,包括“學會”多線程編程需要掌握的基礎以及Python兩個線程標準庫的完整介紹及使用示例。
注意:本文基于Python2.4完成,;如果看到不明白的詞匯請記得百度谷歌或維基,whatever。
1. 線程基礎
1.1. 線程狀態
線程有5種狀態,狀態轉換的過程如下圖所示:
1.2. 線程同步(鎖)
多線程的優勢在于可以同時運行多個任務(至少感覺起來是這樣)。但是當線程需要共享數據時,可能存在數據不同步的問題??紤]這樣一種情況:一個列表里所有元素都是0,線程"set"從后向前把所有元素改成1,而線程"print"負責從前往后讀取列表并打印。那么,可能線程"set"開始改的時候,線程"print"便來打印列表了,輸出就成了一半0一半1,這就是數據的不同步。為了避免這種情況,引入了鎖的概念。
鎖有兩種狀態——鎖定和未鎖定。每當一個線程比如"set"要訪問共享數據時,必須先獲得鎖定;如果已經有別的線程比如"print"獲得鎖定了,那么就讓線程"set"暫停,也就是同步阻塞;等到線程"print"訪問完畢,釋放鎖以后,再讓線程"set"繼續。經過這樣的處理,打印列表時要么全部輸出0,要么全部輸出1,不會再出現一半0一半1的尷尬場面。
線程與鎖的交互如下圖所示:
1.3. 線程通信(條件變量)
然而還有另外一種尷尬的情況:列表并不是一開始就有的;而是通過線程"create"創建的。如果"set"或者"print" 在"create"還沒有運行的時候就訪問列表,將會出現一個異常。使用鎖可以解決這個問題,但是"set"和"print"將需要一個無限循環——他們不知道"create"什么時候會運行,讓"create"在運行后通知"set"和"print"顯然是一個更好的解決方案。于是,引入了條件變量。
條件變量允許線程比如"set"和"print"在條件不滿足的時候(列表為None時)等待,等到條件滿足的時候(列表已經創建)發出一個通知,告訴"set" 和"print"條件已經有了,你們該起床干活了;然后"set"和"print"才繼續運行。
線程與條件變量的交互如下圖所示:
1.4. 線程運行和阻塞的狀態轉換
最后看看線程運行和阻塞狀態的轉換。
新聞熱點
疑難解答