一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

腳本之家,腳本語言編程技術及教程分享平臺!
分類導航

Python|VBS|Ruby|Lua|perl|VBA|Golang|PowerShell|Erlang|autoit|Dos|bat|

服務器之家 - 腳本之家 - Python - 深入了解Python的多線程基礎

深入了解Python的多線程基礎

2022-03-08 00:11程序員-夏天 Python

這篇文章主要為大家介紹了Python多線程基礎,具有一定的參考價值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助

線程

線程(Thread),有時也被稱為輕量級進程(Lightweight Process,LWP),是操作系統獨?調度和分派的基本單位,本質上就是一串指令的集合。

?個標準的線程由線程id、當前指令指針(PC),寄存器集合和堆棧組成,它是進程中的?個實體,線程本身不擁有系統資源,只擁有?點?在運?中必不可少的資源(如程序計數器、寄存器、棧),但它可與同屬?個進程的其它線程共享進程所擁有的全部資源。線程不能夠獨?執?,必須依存在進程中。

多線程

多線程就是使用多個線程同時執行任務,實現了任務的并行執行,從而提高程序運行效率的方法。

試想一下,如果在單個線程內執行多個任務(比如發送網絡請求等),如果前面的任務比較耗時,而后面的任務需要等待前面的任務執行完才能執行,這樣會影響任務執行效率,那么就可以使用多線程去執行這些任務,任務可以同時進行,那么將大大的提高執行效率。

Python多線程

在Python中,提供了threading模塊來實現多進程操作,這個模塊是基于較低級的模塊 _thread 的基礎上建立的,提供了更易用的高級多線程API。

創建線程

可以通過threading模塊中的Thread類來創建線程對象。

Thread語法結構:

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

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

Thread常用方法

  • start():啟動線程,并調用該線程中的run()方法
  • run():線程啟動時運行的方法,正是它去調用target指定的函數
  • join(timeout=None):讓當前調用者線程(一般為主線程)等待,直到該線程結束,timeout是可選的超時時間
  • is_alive():返回當前線程是否存活
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import threading
import time
def work(i):
    print("子線程'{}'work正在運行......".format(threading.current_thread().name))
    time.sleep(i)
    print("子線程'{}'運行結束......".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("主線程結束")

執行結果為:

深入了解Python的多線程基礎

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

GIL鎖

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

線程池

在之前的文章說過,進程有進程池的機制,同樣,線程也有線程池。線程池可以在程序啟動時就創建自定義數量的空閑的線程,程序只要將一個任務提交給線程池,線程池就會啟動一個空閑的線程來執行它。當該任務執行結束后,該線程并不會死亡,而是再次返回到線程池中變成空閑狀態,等待下一個任務的執行。

multiprocessing.dummy里面也有一個Pool對象,它其實就是線程的封裝,使用起來和multiprocessing的Pool非常類似。它們api都是通用的,簡單地說,multiprocessing.dummymultiprocessing進程池模塊復制的一個線程池模塊,強調一下,這里線程池也是受到GIL限制的。

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

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
from multiprocessing.dummy import Pool
import time
def work(i):
    print("work'{}'執行中......".format(i))
    time.sleep(2)
    print("work'{}'執行完畢......".format(i))
if __name__ == '__main__':
    # 創建線程池
    # Pool(5) 表示創建容量為5個線程的線程池
    pool = Pool(5)
    for i in range(10):
        pool.apply_async(work, (i, ))
    pool.close()
    pool.join()

總結

由于Python中的多線程受GIL鎖的限制,導致不能利用機器多核的特性,只能利用單核,是假的多線程,但是也不是一無是處,對于IO密集型任務,多線程是能夠有效提升運行效率的,這是因為單線程下有IO操作時,會進行IO等待,這樣會浪費等待的這段時間,而開啟多線程能在線程A等待時,自動切換到線程B,可以減少不必要的時間浪費,從而能提升程序運行效率,但是也不是最好的選擇,對于處理IO密集型任務,在Python還有更好的選擇協程,在后續文章會介紹。

本篇文章就到這里了,希望能夠給你帶來幫助,也希望您能夠多多關注服務器之家的更多內容!

原文鏈接:https://blog.csdn.net/weixin_50097774/article/details/121443474

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 天天干天天日天天射天天操毛片 | 四虎免费在线视频 | 精品国产爱久久 | 交换性关系中文字幕6 | 亚洲欧美国产在线 | 国产精品热久久毛片 | 日韩欧美色图 | 日韩成人小视频 | 91亚洲视频在线观看 | 国产福利一区二区三区四区 | 白丝打脚枪 | 亚洲视频免 | 毛片www| 大学第一次基本都没了 | 美女撒尿无遮挡免费中国 | 亚洲日本aⅴ片在线观看香蕉 | 视频一区二区 村上凉子 | 日本一区视频在线 | 欧美亚洲第一区 | 亚洲AV福利天堂一区二区三 | 999久久久免费精品国产牛牛 | 暖暖的韩国免费观看 | 2020国产精品永久在线观看 | 久久精品国产亚洲AV天美18 | 狐媚小说| chinese国产人妖videos | 亚洲福利一区 | 免费看黄色大片 | 国产一级视频久久 | 美女隐私部位视频网站 | 日本色频| 国产一区二区在线观看视频 | zozzozozozo大| 忘忧草高清 | 荡女人人爱全文免费阅读 | 国产精品久久久久jk制服 | 国产精品久久久久久福利 | 欧美精品国产一区二区 | 韩剧消失的眼角膜免费完整版 | 我要看免费毛片 | 免费成年网 |