欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

深入了解Python的多線程基礎(chǔ)

 更新時(shí)間:2021年11月25日 15:58:35   作者:程序員-夏天  
這篇文章主要為大家介紹了Python多線程基礎(chǔ),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助

線程

線程(Thread),有時(shí)也被稱為輕量級進(jìn)程(Lightweight Process,LWP),是操作系統(tǒng)獨(dú)?調(diào)度和分派的基本單位,本質(zhì)上就是一串指令的集合。

?個(gè)標(biāo)準(zhǔn)的線程由線程id、當(dāng)前指令指針(PC),寄存器集合和堆棧組成,它是進(jìn)程中的?個(gè)實(shí)體,線程本身不擁有系統(tǒng)資源,只擁有?點(diǎn)?在運(yùn)?中必不可少的資源(如程序計(jì)數(shù)器、寄存器、棧),但它可與同屬?個(gè)進(jìn)程的其它線程共享進(jìn)程所擁有的全部資源。線程不能夠獨(dú)?執(zhí)?,必須依存在進(jìn)程中。

多線程

多線程就是使用多個(gè)線程同時(shí)執(zhí)行任務(wù),實(shí)現(xiàn)了任務(wù)的并行執(zhí)行,從而提高程序運(yùn)行效率的方法。

試想一下,如果在單個(gè)線程內(nèi)執(zhí)行多個(gè)任務(wù)(比如發(fā)送網(wǎng)絡(luò)請求等),如果前面的任務(wù)比較耗時(shí),而后面的任務(wù)需要等待前面的任務(wù)執(zhí)行完才能執(zhí)行,這樣會影響任務(wù)執(zhí)行效率,那么就可以使用多線程去執(zhí)行這些任務(wù),任務(wù)可以同時(shí)進(jìn)行,那么將大大的提高執(zhí)行效率。

Python多線程

在Python中,提供了threading模塊來實(shí)現(xiàn)多進(jìn)程操作,這個(gè)模塊是基于較低級的模塊 _thread 的基礎(chǔ)上建立的,提供了更易用的高級多線程API。

創(chuàng)建線程

可以通過threading模塊中的Thread類來創(chuàng)建線程對象。

Thread語法結(jié)構(gòu):

threading.Thread(group, target, name, daemon)

  • group:默認(rèn)為None(該參數(shù)是為了以后實(shí)現(xiàn)ThreadGroup類而保留的)
  • target:在run方法中調(diào)用的可調(diào)用對象,即線程要執(zhí)行的任務(wù)
  • name:線程名稱,可以不設(shè)定,默認(rèn)為"Thread-N"形式的名稱
  • args:給target指定的函數(shù)傳遞的參數(shù),以元組的?式傳遞
  • kwargs:給target指定的函數(shù)傳遞命名參數(shù)
  • daemon:默認(rèn)為None,將顯式地設(shè)置該線程是否為守護(hù)模式。如果是None,線程將繼承當(dāng)前線程的守護(hù)模式屬性

Thread常用方法

  • start():啟動線程,并調(diào)用該線程中的run()方法
  • run():線程啟動時(shí)運(yùn)行的方法,正是它去調(diào)用target指定的函數(shù)
  • join(timeout=None):讓當(dāng)前調(diào)用者線程(一般為主線程)等待,直到該線程結(jié)束,timeout是可選的超時(shí)時(shí)間
  • is_alive():返回當(dāng)前線程是否存活
import threading
import time
def work(i):
    print("子線程'{}'work正在運(yùn)行......".format(threading.current_thread().name))
    time.sleep(i)
    print("子線程'{}'運(yùn)行結(jié)束......".format(threading.current_thread().name))
if __name__ == '__main__':
    print("主線程{}啟動".format(threading.current_thread().name))
    # 獲取線程的名稱
    threads = []
    for i in range(5):
        t = threading.Thread(target=work, args=(i,))
    # 啟動線程
        threads.append(t)
        t.start()
    for t in threads:
        t.join()
    print("主線程結(jié)束")

執(zhí)行結(jié)果為:

上述代碼中使用t.join()的功能就是讓主線程等待所有子線程結(jié)束后才結(jié)束,如果想設(shè)置守護(hù)線程(主線程結(jié)束,子線程也隨之結(jié)束,無論任務(wù)執(zhí)行完成與否)的話,可以使用t.daemon = True。

GIL鎖

GIL的全稱是Global Interpreter Lock(全局解釋器鎖),這個(gè)鎖最初的設(shè)計(jì)是為了保證同一份數(shù)據(jù)不能被多個(gè)線程同時(shí)修改,每個(gè)線程在執(zhí)行任務(wù)的時(shí)候都需要先獲取GIL,保證同一時(shí)刻只有一個(gè)線程可以執(zhí)行,即同一時(shí)刻只有一個(gè)線程在解釋器中運(yùn)行,因此Python中的多線程是假的多線程,不是真正意義上的多線程。 如果程序中有多個(gè)線程執(zhí)行任務(wù),那么多個(gè)線程會被解釋器輪流執(zhí)行,只不過是切換的很快、很頻繁,給人一種多線程“同時(shí)”在執(zhí)行的錯(cuò)覺。

線程池

在之前的文章說過,進(jìn)程有進(jìn)程池的機(jī)制,同樣,線程也有線程池。線程池可以在程序啟動時(shí)就創(chuàng)建自定義數(shù)量的空閑的線程,程序只要將一個(gè)任務(wù)提交給線程池,線程池就會啟動一個(gè)空閑的線程來執(zhí)行它。當(dāng)該任務(wù)執(zhí)行結(jié)束后,該線程并不會死亡,而是再次返回到線程池中變成空閑狀態(tài),等待下一個(gè)任務(wù)的執(zhí)行。

multiprocessing.dummy里面也有一個(gè)Pool對象,它其實(shí)就是線程的封裝,使用起來和multiprocessing的Pool非常類似。它們api都是通用的,簡單地說,multiprocessing.dummymultiprocessing進(jìn)程池模塊復(fù)制的一個(gè)線程池模塊,強(qiáng)調(diào)一下,這里線程池也是受到GIL限制的。

使用方式和multiprocessing.Pool一致,具體參考Python進(jìn)程池。

from multiprocessing.dummy import Pool
import time
def work(i):
    print("work'{}'執(zhí)行中......".format(i))
    time.sleep(2)
    print("work'{}'執(zhí)行完畢......".format(i))
if __name__ == '__main__':
    # 創(chuàng)建線程池
    # Pool(5) 表示創(chuàng)建容量為5個(gè)線程的線程池
    pool = Pool(5)
    for i in range(10):
        pool.apply_async(work, (i, ))
    pool.close()
    pool.join()

總結(jié)

由于Python中的多線程受GIL鎖的限制,導(dǎo)致不能利用機(jī)器多核的特性,只能利用單核,是假的多線程,但是也不是一無是處,對于IO密集型任務(wù),多線程是能夠有效提升運(yùn)行效率的,這是因?yàn)閱尉€程下有IO操作時(shí),會進(jìn)行IO等待,這樣會浪費(fèi)等待的這段時(shí)間,而開啟多線程能在線程A等待時(shí),自動切換到線程B,可以減少不必要的時(shí)間浪費(fèi),從而能提升程序運(yùn)行效率,但是也不是最好的選擇,對于處理IO密集型任務(wù),在Python還有更好的選擇協(xié)程,在后續(xù)文章會介紹。

本篇文章就到這里了,希望能夠給你帶來幫助,也希望您能夠多多關(guān)注腳本之家的更多內(nèi)容!

相關(guān)文章

  • python多線程高級鎖condition簡單用法示例

    python多線程高級鎖condition簡單用法示例

    這篇文章主要介紹了python多線程高級鎖condition簡單用法,結(jié)合實(shí)例形式分析了condition對象常用方法及相關(guān)使用技巧,需要的朋友可以參考下
    2019-11-11
  • Pytorch基本變量類型FloatTensor與Variable用法

    Pytorch基本變量類型FloatTensor與Variable用法

    今天小編就為大家分享一篇Pytorch基本變量類型FloatTensor與Variable用法,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-01-01
  • pycharm使用docker容器開發(fā)的詳細(xì)教程

    pycharm使用docker容器開發(fā)的詳細(xì)教程

    這篇文章主要介紹了pycharm使用docker容器開發(fā)的詳細(xì)教程,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2023-01-01
  • python用post訪問restful服務(wù)接口的方法

    python用post訪問restful服務(wù)接口的方法

    今天小編就為大家分享一篇python用post訪問restful服務(wù)接口的方法,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2018-12-12
  • python模糊圖片過濾的方法

    python模糊圖片過濾的方法

    今天小編就為大家分享一篇python模糊圖片過濾的方法,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2018-12-12
  • python安裝本地whl的實(shí)例步驟

    python安裝本地whl的實(shí)例步驟

    在本篇文章里小編給大家整理的是關(guān)于python安裝本地whl的實(shí)例步驟,有需要的朋友們可以學(xué)習(xí)下。
    2019-10-10
  • Python編程實(shí)現(xiàn)凱撒密碼加密示例

    Python編程實(shí)現(xiàn)凱撒密碼加密示例

    這篇文章主要介紹了使用Python語言編程實(shí)現(xiàn)對凱撒密碼加密的示例詳解有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步早日升職加薪
    2021-10-10
  • python之NAN和INF值處理方式

    python之NAN和INF值處理方式

    這篇文章主要介紹了python之NAN和INF值處理方式,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-05-05
  • 關(guān)于python3?opencv?圖像二值化的問題(cv2.adaptiveThreshold函數(shù))

    關(guān)于python3?opencv?圖像二值化的問題(cv2.adaptiveThreshold函數(shù))

    這篇文章主要介紹了python3?opencv?圖像二值化cv2.adaptiveThreshold函數(shù)的相關(guān)知識,結(jié)合示例代碼介紹了adaptiveThreshold方法的用法,需要的朋友可以參考下
    2022-04-04
  • 使用python獲取cpu每秒的使用率

    使用python獲取cpu每秒的使用率

    這篇文章主要介紹了使用python獲取cpu每秒的使用率,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-05-05

最新評論