您好,登錄后才能下訂單哦!
本篇文章為大家展示了Threading多線程模塊怎么在Python中使用,內容簡明扼要并且容易理解,絕對能使你眼前一亮,通過這篇文章的詳細介紹希望你能有所收獲。
進程
是操作系統中當前程序的一次執行。要知道擁有單個CPU的電腦,在嚴格意義上,一個時間點上操作系統只能進行同一個工作命令。由于計算機的運行速度快,在工作時可以運行一會A代碼,運行一會B代碼,交錯運行,由于運算速度快,所以一般看來它好像可以同時進行多個程序--這就是多進程。
線程
線程是程序中一個單一的順序控制流程。進程內一個相對獨立的、可調度的執行單元,是系統獨立調度和分派CPU的基本單位,這里的單位指運行中的程序的調度單位。在單個程序中同時運行多個線程完成不同的工作,稱為多線程。線程還可以自己創建、撤銷和切換。就像拿蘋果,如果一根手指可以辦到,那它就是單線程,如果需要多根手指,那就是多線程。
進程和線程的區別
(1)進程是資源的分配和調度的一個獨立單元,而線程是CPU調度的基本單元
(2)同一個進程中可以包括多個線程,并且線程共享整個進程的資源(寄存器、堆棧、上下文),一個進程至少包括一個線程。
(3)進程結束后它擁有的所有線程都將銷毀,而線程的結束不會影響同個進程中的其他線程的結束
(4)線程是輕量級的進程,它的創建和銷毀所需要的時間比進程小很多,所有操作系統中的執行功能都是創建線程去完成的
(5)線程中執行時一般都要進行同步和互斥,因為他們共享同一進程的所有資源(資源競爭)
(6)線程有自己的私有屬性TCB,線程id,寄存器、硬件上下文,而進程也有自己的私有屬性進程控制塊PCB,這些私有屬性是不被共享的,用來標示一個進程或一個線程的標志
子進程與子線程的區別
進程和線程的區別在于粒度不同, 進程之間的變量(或者說是內存)是不能直接互相訪問的, 而線程可以, 線程一定會依附在某一個進程上執行.我舉個例子, 你在Windows下開一個IE瀏覽器, 這個IE瀏覽器是一個進程. 你用瀏覽器去打開一個pdf, IE就去調用Acrobat去打開, 這時Acrobat是一個獨立的進程, 就是IE的子進程.而IE自己本身同時用同一個進程開了2個網頁, 并且同時在跑兩個網頁上的腳本, 這兩個網頁的執行就是IE自己通過兩個線程實現的.值得注意的是, 線程仍然是IE的內容, 而子進程Acrobat嚴格來說就不屬于IE了, 是另外一個程序,之所以是IE的子進程, 只是受IE調用而啟動的而已。
這里大家可能會疑惑,進程分配內存空間的依據是啥?其實進程建立,系統會為其分配虛擬地址空間4GB(在32位系統中),具體分配情況要取決于該包含的所有可執行模塊或dll模塊的代碼和數據,還包含動態內存分配的空間(如線程中堆棧的分配)
好了,上面介紹了基本的線程及進程的概念,接下來可以開始正題了,這里主要總結下python內的Threading模塊
python多線程之Threading
單線程
額,這個忽略吧。。。操作系統單任務的處理,排好隊,一個一個來就是單線程。
多線程
多線程Threading一般可以通過兩種渠道來實現:一種是通過繼承Thread類,重寫它的run方法;另一種是創建一個threading.Thread對象,在它的初始化函數(__init__)中將可調用對象作為參數傳入,本質上來講,兩種方式一樣。
來一發實例:
# -*- coding: utf-8 -*- import threading import time #方式二是方式一的具體,方式一為類構造,方式二為方法實例構造,其實本質都是一樣,都是調用threading.Thread模塊 #方式一 count = 0 class Counter(threading.Thread): def __init__(self, lock, threadName): #注意:一定要顯式的調用父類的初始化函數,這里可以指定生成的線程名,可以是*args、**kwargs #def __init__(self, group=None, target=None, name=None, args=(), kwargs={}),其中group是預留的,將來用于擴展 super(Counter, self).__init__(name=threadName) self.lock = lock def run(self): global count self.lock.acquire() for i in range(100): count = count + 1 self.lock.release() #方式二 lockA = threading.Lock() lockB = threading.Lock() rLock = threading.RLock() condt = threading.Condition() event = threading.Event() def add(lockA): global count #定義當前資源只能單線程訪問,鎖住后完成資源調用一定要釋放鎖,不然會造成死鎖狀態,甚至程序崩潰 lockA.acquire() for i in range(1000): count = count + 1 #資源調用完畢,釋放鎖 lockA.release() def addRunner(): for i in range(2): th = threading.Thread(target=rloc, args=(rLock,)) #開啟線程,從此刻起,多線程開始,主線程繼續前行 th.start() #調用Thread.join[timeout]將會使主調線程堵塞,直到被調用線程運行結束或超時。參數timeout是一個數值類型,表示超時時間 th.join() print '----- %s is start -----' % th.getName() print "over" #RLock允許在同一線程中被多次acquire,避免單線程出現思索情況 def rloc(rLock): rLock.acquire() for i in range(2): rLock.acquire() print i, rLock.release() rLock.release() print "over!" def rlocRun(): for i in range(2): th = threading.Thread(target=rloc, args=(rLock,)) th.start() print '----- %s is start -----' % th.getName() print "over" #現在出現復雜的場景,多個線程需要調用多個共同的資源,此時就需要threading.Condition出馬,加入簡單的說就是A搞完了A的事 # ,就發廣播說明自己搞定了,其它人可以進來了,B同理。 def cond(cond): #適合那種主動休眠,被動喚醒的場景 cond.acquire() global count for i in range(1000): count = count + 1 #喚醒一個掛起的線程(如果存在掛起的線程),提醒當前的掛起的線程看看其它的鎖開了沒有,如果開了就搞其他的事。 #注意:notify()方法不會釋放所占用的瑣。 cond.notify() #wait方法釋放內部所占用的瑣,同時線程被掛起,直至接收到通知被喚醒或超時 cond.wait(5) #相信大家應該看出問題來了,最后一個線程咋辦列,沒人喚醒啊,這個時候應該做過一個判斷 cond.release() print "over!" def condRun(): global condt for i in range(0, 3): th = threading.Thread(target=cond, args=(condt, )) th.start() print '----- %s is start -----' % th.getName() print "over" #此時可能會有一點問題,就是線程的同步(并發)問題怎么解決呢?此時threading.Event出馬 def even(n, event): while not event.isSet(): print 'Thread %s is ready' % n time.sleep(1) #同condition一樣,掛起該線程,等待set開關 event.wait() while event.isSet(): print 'Thread %s is running' % n time.sleep(1) def evenRun(): for i in range(0, 2): th = threading.Thread(target=even, args=(i, event)) th.start() time.sleep(3) print '----- event is set -----' event.set() time.sleep(3) print '----- event is clear -----' event.clear() if __name__ == "__main__": Counter(lockA, "thread1").start() addRunner() rlocRun() condRun() evenRun()
上述內容就是Threading多線程模塊怎么在Python中使用,你們學到知識或技能了嗎?如果還想學到更多技能或者豐富自己的知識儲備,歡迎關注億速云行業資訊頻道。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。