python 多線程編程

轉自:http://hi.baidu.com/seekvista/blog/item/d626f8172cf0b608c83d6d14.html

我們在做軟件開發的時候很多要用到多線程技術。例如如果做一個下載軟件象flashget就要用到、象在線視頻工具realplayer也要用到因爲要同時下載media stream還要播放。其實例子是很多的。
         線程相對進程來說是“輕量級”的,操作系統用較少的資源創建和管理線程。程序中的線程在相同的內存空間中執行,並共享許多相同的資源。
python中如何創建一個線程對象:
         如果你要創建一個線程對象,很簡單,只要你的類繼承
threading.Thread,然後在__init__裏首先調用threading.Thread__init__方法即可:
import threading
class mythread(threading.Thread):
def __init__(self, threadname):
threading.Thread.__init__(self, name = threadname)
....

         這才僅僅是個空線程,我可不是要他拉空車的,他可得給我乾點實在活。很簡單,重寫類的
run()方法即可,把你要在線程執行時做的事情都放到裏面
import threading
import time
class mythread(threading.Thread):
def __init__(...):
....
def run(self):
for i in range(10):
print self.getName, i
time.sleep(1)

         以上代碼我們讓這個線程在執行之後每隔1秒輸出一次信息到屏幕,10次後結束
getName()threading.Thread類的一個方法,用來獲得這個線程對象的name。還有一個方法setName()當然就是來設置這個線程對象的name的了。
         如果要創建一個線程,首先就要先創建一個線程對象
mythread1 = mythread('mythread 1')
         一個線程對象被創建後,他就處於“
born”(誕生狀態),如何讓這個線程對象開始運行呢?只要調用線程對象的start()方法即可:
mythread1.start()
現在線程就處於“
ready”狀態或者也稱爲“runnable”狀態。
         奇怪嗎?不是已經
start了嗎?爲什麼不稱爲“running”狀態呢?其實是有原因的。因爲我們的計算機一般是不具有真正並行處理能力的。我們所謂的多線程只是把時間分成片段,然後隔一個時間段就讓一個線程執行一下,然後進入“sleeping ”狀態,然後喚醒另一個在“sleeping”的線程,如此循環runnable->sleeping->runnable... ,只是因爲計算機執行速度很快,而時間片段間隔很小,我們感受不到,以爲是同時進行的。所以說一個線程在start了之後只是處在了可以運行的狀態,他什麼時候運行還是由系統來進行調度的。
         那一個線程什麼時候會“
dead”呢?一般來說當線程對象的run方法執行結束或者在執行中拋出異常的話,那麼這個線程就會結束了。系統會自動對“dead”狀態線程進行清理。
         如果一個線程
t1在執行的過程中需要等待另一個線程t2執行結束後才能運行的話那就可以在t1在調用t2join()方法
....
def t1(...):
...
t2.join()
...

這樣
t1在執行到t2.join()語句後就會等待t2結束後纔會繼續運行。
         但是假如
t1是個死循環的話那麼等待就沒有意義了,那怎麼辦呢?可以在調用t2join()方法的時候給一個浮點數做超時參數,這樣這個線程就不會等到花兒也謝了了。我等你10s,你不回來我還不允許我改嫁啊?:)
def t1(...):
...
t2.join(10)
...

         如果一個進程的主線程運行完畢而子線程還在執行的話,那麼進程就不會退出,直到所有子線程結束爲止,如何讓主線程結束的時候其他子線程也乖乖的跟老大撤退呢?那就要把那些不聽話的人設置爲聽話的小弟,使用線程對象的
setDaemon()方法,參數爲bool型。True的話就代表你要聽話,我老大(主線程)扯呼,你也要跟着撤,不能拖後腿。如果是False的話就不用那麼聽話了,老大允許你們將在外軍命有所不受的。需要注意的是setDaemon()方法必須在線程對象沒有調用start()方法之前調用,否則沒效果。
t1 = mythread('t1')
print t1.getName(),t1.isDaemon()
t1.setDaemon(True)
print t1.getName(),t1.isDaemon()
t1.start()
print 'main thread exit'

         當執行到
print 'main thread exit' 後,主線程就退出了,當然t1這個線程也跟着結束了。但是如果不使用t1線程對象的setDaemon()方法的話,即便主線程結束了,還要等待t1線程自己結束才能退出進程。isDaemon()是用來獲得一個線程對象的Daemonflag狀態的。
         如何來獲得與線程有關的信息呢?
獲得當前正在運行的線程的引用:
running = threading.currentThread()
獲得當前所有活動對象(即
run方法開始但是未終止的任何線程)的一個列表:
threadlist = threading.enumerate()
獲得這個列表的長度:
threadcount = threading.activeCount()
查看一個線程對象的狀態調用這個線程對象的
isAlive()方法,返回1代表處於“runnable”狀態且沒有“dead”:
threadflag = threading.isAlive()

發佈了74 篇原創文章 · 獲贊 6 · 訪問量 42萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章