您好,登錄后才能下訂單哦!
本篇文章為大家展示了如何在Python中使用threading和multiprocessing多線程模塊,內容簡明扼要并且容易理解,絕對能使你眼前一亮,通過這篇文章的詳細介紹希望你能有所收獲。
線程的狀態圖:
Python中常使用的線程模塊
thread(低版本使用的),threading
Queue
multiprocessing
threading
thread模塊是Python低版本中使用的,高版本中被threading代替了。threading模塊提供了更方便的API來操作線程。
threading.Thread
Thread是threading模塊中最重要的類之一,可以使用它來創建線程。創建新的線程有兩種方法:
方法一:直接創建threading.Thread類的對象,初始化時將可調用對象作為參數傳入。
方法二:通過繼承Thread類,重寫它的run方法。
Thread類的構造方法:
__init__(group=None, target=None, name=None, args=(), kwargs=None, verbose=None)
參數說明:
group:線程組,目前還沒有實現,庫引用中提示必須是None。
target:要執行的方法;
name:線程名;
args/kwargs:要傳入方法的參數。
Thread類擁有的實例方法:
isAlive():返回線程是否在運行。正在運行指的是啟動后,終止前。
getName(name)/setName(name):獲取/設置線程名。
isDaemon(bool)/setDaemon(bool):獲取/設置是否為守護線程。初始值從創建該線程的線程繼承而來,當沒有非守護線程仍在運行時,程序將終止。
start():啟動線程。
join([timeout]):阻塞當前上下文環境的線程,直到調用此方法的線程終止或到達指定的等待時間timeout(可選參數)。即當前的線程要等調用join()這個方法的線程執行完,或者是達到規定的時間。
直接創建threading.Thread類的對象
實例:
from threading import Thread import time def run(a = None, b = None) : print a, b time.sleep(1) t = Thread(target = run, args = ("this is a", "thread")) #此時線程是新建狀態 print t.getName()#獲得線程對象名稱 print t.isAlive()#判斷線程是否還活著。 t.start()#啟動線程 t.join()#等待其他線程運行結束
執行結果:
Thread-1 False this is a thread
注意:
t = Thread(target = run, args = ("this is a", "thread"))
這句只是創建了一個線程,并未執行這個線程,此時線程處于新建狀態。
t.start()#啟動線程
啟動線程,此時線程扔為運行,只是處于準備狀態。
自定義函數run(),使我們自己根據我們需求自己定義的,函數名可以隨便取,run函數的參數來源于后面的args元組。
通過繼承Thread類
實例:
from threading import Thread import time class MyThread(Thread) : def __init__(self, a) : super(MyThread, self).__init__() #調用父類的構造方法 self.a = a def run(self) : print "sleep :", self.a time.sleep(self.a) t1 = MyThread(2) t2 = MyThread(4) t1.start() t2.start() t1.join() t2.join()
執行結果:
由于創建了兩個并發執行的線程t1和t2,并發線程的執行時間不定,誰先執行完的時間也不定,所以執行后打印的結果順序也是不定的。每一次執行都有可能出現不同的結果。
注意:
繼承Thread類的新類MyThread構造函數中必須要調用父類的構造方法,這樣才能產生父類的構造函數中的參數,才能產生線程所需要的參數。新的類中如果需要別的參數,直接在其構造方法中加即可。
同時,新類中,在重寫父類的run方法時,它默認是不帶參數的,如果需要給它提供參數,需要在類的構造函數中指定,因為在線程執行的過程中,run方法時線程自己去調用的,不用我們手動調用,所以沒法直接給傳遞參數,只能在構造方法中設定好參數,然后再run方法中調用。
針對join()函數用法的實例:
# encoding: UTF-8 import threading import time def context(tJoin): print 'in threadContext.' tJoin.start() # 將阻塞tContext直到threadJoin終止。 tJoin.join() # tJoin終止后繼續執行。 print 'out threadContext.' def join(): print 'in threadJoin.' time.sleep(1) print 'out threadJoin.' tJoin = threading.Thread(target=join) tContext = threading.Thread(target=context, args=(tJoin,)) tContext.start()
執行結果:
in threadContext. in threadJoin. out threadJoin. out threadContext.
解析:
主程序中這句tJoin = threading.Thread(target=join)執行后,只是創建了一個線程對象tJoin,但并未啟動該線程。
tContext = threading.Thread(target=context, args=(tJoin,)) tContext.start()
上面這兩句執行后,創建了另一個線程對象tContext并啟動該線程(打印in threadContext.),同時將tJoin線程對象作為參數傳給context函數,在context函數中,啟動了tJoin這個線程,同時該線程又調用了join()函數(tJoin.join()),那tContext線程將等待tJoin這線程執行完成后,才能繼續tContext線程后面的,所以先執行join()函數,打印輸出下面兩句:
in threadJoin. out threadJoin.
tJoin線程執行結束后,繼續執行tContext線程,于是打印輸出了out threadContext.,于是就看到我們上面看到的輸出結果,并且無論執行多少次,結果都是這個順序。但如果將context()函數中tJoin.join()這句注釋掉,再執行該程序,打印輸出的結果順序就不定了,因為此時這兩線程就是并發執行的。
multiprocessing.dummy
Python中線程multiprocessing模塊與進程使用的同一模塊。使用方法也基本相同,唯一不同的是,from multiprocessing import Pool這樣導入的Pool表示的是進程池;
from multiprocessing.dummy import Pool這樣導入的Pool表示的是線程池。這樣就可以實現線程里面的并發了。
線程池實例:
import time from multiprocessing.dummy import Pool as ThreadPool #給線程池取一個別名ThreadPool def run(fn): time.sleep(2) print fn if __name__ == '__main__': testFL = [1,2,3,4,5] pool = ThreadPool(10)#創建10個容量的線程池并發執行 pool.map(run, testFL) pool.close() pool.join()
執行結果:
這里的pool.map()函數,跟進程池的map函數用法一樣,也跟內建的map函數一樣。
上述內容就是如何在Python中使用threading和multiprocessing多線程模塊,你們學到知識或技能了嗎?如果還想學到更多技能或者豐富自己的知識儲備,歡迎關注億速云行業資訊頻道。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。