深入了解Python的多執行緒基礎

2022-09-24 10:45:16 字數 2628 閱讀 7544

目錄

執行緒(thread),有時也被稱為輕量級程序(lightweight process,lwp),是操作系**排程和分派的基本單位,本質上就是一串指令的集合。

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

多執行緒就是使用多個執行緒同時執行任務,實現了任務的並行執行,從而提高程式執行效率的方法。

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

在python中,提供了threading模組來實現多程序操作,這個模組是基於較低階的模組 _thread 的基礎上建立的,提供了更易用的高階多執行緒api。

可以通過threading模組中的類來建立執行緒物件。

thread語法結構:

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

thread常用方法

import threading

import time

def work(i):

print("子執行緒'{}'work正在執行......".format(threading.current_thread().name))

time.sleep(i)

print("子執行緒'{}'執行結束......".format(thrznjoxckpeading.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("主線程結束")

執行結果為:

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

gil的全稱是global interpreter lock(全域性直譯器鎖),這個鎖最初的設計是為了保證同乙份資料不能被多個執行緒同時修改,每個執行緒在執行任務的時候都需要先獲取gil,保證同一時刻只有乙個執行緒可以執行,即同一時刻只有乙個執行緒在直譯器中執行,因此python中的多執行緒是假的多執行緒,不是真正意義上的多執行緒。 如果程式中有多個執行緒執行任務,那麼多個執行緒會被直譯器輪流執行,只不過是切換的很快、很頻繁,給人一種多執行緒「同時」在執行的錯覺。

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

multiprocessing.dummy裡面也有乙個pool物件,它其實就是執行緒的封裝,使用起來和multiprocessing的pool非常類似。它們api都是通用的,簡單地說,multiprocessing.dummy是multiprocessing程序池模組複製的乙個執行緒池模組,強調一下,這裡執行緒池也是受到gil限制的。

使用方式和multiprocessing.pool一致,具體參考python程序池。

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還有更好的選擇協程,在後續文章會介紹。

本文標題: 深入了解python的多執行緒基礎

本文位址: /jiaoben/python/440898.html

深入了解Python的繼承

目錄 繼承的概念 子類 擁有 父類 的所有 方法 和 屬性 不使用繼承類 class animal def eat self print 吃 def drink self print 喝 def run self print 跑 def sleep self print 睡 class dog de...

深入了解python的函式引數

目錄 這是乙個求等差數列和的函式,使用必需要傳入乙個引數n,這就是位置引數 def sum n sum 0 i 1while i n sum i i 1 return sum result sum 100 print result 預設引數就是,我在函式中已經將乙個引數提前設定好了值,如果你沒有傳入...

深入了解Python中的變數

目錄 變數,英文叫做 variable。在 電腦科學概述 中是這樣定義的,高階程式語言允許使用描述性的名字指向主儲存器中的位置,而不必再使用數字位址,這樣的名字稱為變數 variable 之所以是這樣取名是因為,隨著程式的執行,只要改變儲存在這個位置裡的值,那麼與改名字相聯絡的值就會改變。從形式上看...