初识python多线程
1) 在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,time
class MyThread(threading.Thread):
def __init__(self,threadname):
threading.Thread.__init__(self,name=threadname)
def run(self):
'''
run 方法
'''
for i in xrange(10):
print self.getName,i
time.sleep(1)
以上代碼如果被執行之后會每隔1秒輸出一次信息到屏幕,10次后結束。其中這里getName()是threading.Thread類的一個方法,用來獲得這個線程對象的name。還有一個方法setName()當然就是來設置這個線程對象的name的了。
?
如果要創建一個線程,首先就要先創建一個線程對象
my = MyThread('test')一個線程對象被創建后,他就處于“born”(誕生狀態),如何讓這個線程對象開始運行呢?只要調用線程對象的start()方法即可
import threading,time
class MyThread(threading.Thread):
def __init__(self,threadname):
threading.Thread.__init__(self,name=threadname)
def run(self):
for i in xrange(10):
print self.getName(),i
time.sleep(1)
my = MyThread('test')
my.start()
現在線程就處于“ready”狀態或者也稱為“runnable”狀態。
奇怪嗎?不是已經start了嗎?為什么不稱為“running”狀態呢?其實是有原因的。因為我們的計算機一般是不具有真正并行處理能力的。我們所謂的多線程只是把時間分成片段,然后隔一個時間段就讓一個線程執行一下,然后進入“sleeping ”狀態,然后喚醒另一個在“sleeping”的線程,如此循環runnable->sleeping->runnable... ,只是因為計算機執行速度很快,而時間片段間隔很小,我們感受不到,以為是同時進行的。所以說一個線程在start了之后只是處在了可以運行的狀態,他什么時候運行還是由系統來進行調度的。
那一個線程什么時候會“dead”呢?一般來說當線程對象的run方法執行結束或者在執行中拋出異常的話,那么這個線程就會結束了。系統會自動對“dead”狀態線程進行清理。
?
如果一個線程A在執行的過程中需要等待另一個線程tB執行結束后才能運行的話,那就可以在A在調用B的B.join()方法,另外還可以給join()傳入等待的時間。
?
線程對象的setDaemon()方法可以讓子線程隨著主線程的退出而結束,不過注意的是setDaemon()方法必須在線程對象沒有調用start()方法之前調用(默認情況下;在python中,主線程結束后,會默認等待子線程結束后,主線程才退出)。
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()
?
?
2) ?線程同歩隊列?
? ? ?我們經常會采用生產者/消費者關系的兩個線程來處理一個共享緩沖區的數據。例如一個生產者線程接受用戶數據放入一個共享緩沖區里,等待一個消費者線程對數據 取出處理。但是如果緩沖區的太小而生產者和消費者兩個異步線程的速度不同時,容易出現一個線程等待另一個情況。為了盡可能的縮短共享資源并以相同速度工作 的各線程的等待時間,我們可以使用一個“隊列”來提供額外的緩沖區。
?
? ? ??創建一個“隊列”對象
import Queue
myqueue = Queue.Queue(maxsize = 10)
Queue.Queue類即是一個隊列的同步實現。隊列長度可為無限或者有限。可通過Queue的構造函數的可選參數maxsize來設定隊列長度。如果maxsize小于1就表示隊列長度無限。
?
將一個值放入隊列中
myqueue.put(10)調用隊列對象的put()方法在隊尾插入一個項目。put()有兩個參數,第一個item為必需的,為插入項目的值;第二個block為可選參數,默認為1。如果隊列當前為空且block為1,put()方法就使調用線程暫停,直到空出一個數據單元。如果block為0,put方法將引發Full異常。
?
將一個值從隊列中取出
myqueue.get()調用隊列對象的get()方法從隊頭刪除并返回一個項目。可選參數為block,默認為1。如果隊列為空且block為1,get()就使調用線程暫停,直至有項目可用。如果block為0,隊列將引發Empty異常。
另外:? ?q.task_done():表示q.get()返回的項目已被處理; q.join():表示直到隊列中所有項目均被處理。
參考自https://blog.csdn.net/a921800467b/article/details/8579915
總結
以上是生活随笔為你收集整理的初识python多线程的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: C++混淆点-构造函数参数
- 下一篇: websocket python爬虫_p