python threading2種呼叫方式例項

2022-03-18 19:07:25 字數 2399 閱讀 1514

1.認識gil:

說到gil一直是**專家們一直以來想要解決的問題,也是被許多程式設計師詬病的,下面帶領大家看下官方threading模組document中如何去描述對於gil這個全域性直譯器鎖的:

全域性直譯器鎖

所使用的機制

的cpython

直譯器來確保只有乙個執行緒執行的python 

位元組碼在乙個時間。

通過使物件模型(包括關鍵的內建型別,例如

dict

)隱式安全地防止併發訪問

,從而簡化了cpython的實現

。鎖定整個直譯器可以使直譯器更容易進行多執行緒處理,但會犧牲多處理器機器提供的許多並行性。

但是,某些擴充套件模組(標準的或第三方的)被設計為在執行諸如壓縮或雜湊之類的計算密集型任務時釋放gil。

另外,在執行i / o時,始終釋放gil。

過去建立「自由執行緒」直譯器(一種以更精細的粒度鎖定共享資料的直譯器)的努力並未成功,因為在常見的單處理器情況下效能會受到影響。

相信克服該效能問題將使實施更加複雜,因此維護成本更高。

在這裡專門對全域性直譯器鎖的概念引入時說了這麼一段話,第一指明了gil造成了python直譯器一次只有乙個執行緒可以獲取直譯器鎖,也就是直譯器本身是自帶鎖的,誰先拿到誰就可以搶占到cpu的資源,

從而導致了python無論乙個執行緒怎麼去跑,都只能最多跑滿乙個cpu核心,就造成了多核cpu資源的無法利用的帶來的資源浪費,但是這是否就意味著python一無是處呢,答案肯定no!,雖然gil對於cpu密集的支援

不是那麼的友好,但是,對於io密集的支援恰恰是其他語言所無法比擬的,就拿asyncio這這個協程庫來講:

下面就以target進行舉例:

可以看到執行緒的資源搶占效果;證明gil鎖的的確真實存在的;

先在我們如果更換t.join()到t1.start()的後面會發現,執行緒每次不管怎麼執行都是先執行完threading1執行緒,再去執行threading2執行緒,而這完全得益於join()函式:

我們來看原始碼是怎麼解釋join()的:

等待直到執行緒終止。

這將阻塞呼叫執行緒,直到

join()

被呼叫方法

的執行緒終止(正常或通過未處理的異常終止),或者直到發生可選的超時。

講完join():

我們再來認識乙個有趣的引數daemon->守護執行緒:

先看原始碼:

演示daemon:

正常預設daemon為false:

可以看到主線程執行結束後退出後子執行緒繼續執行並輸出了內容,

但是現在如果有個需求要求我們實現主線程退出後必須kill掉子執行緒那麼,如何實現這個需求,這就用到了daemon,我們只需要設定為true:

主線程執行結束後並沒有等待子執行緒

執行完畢就kill掉了子執行緒沒有輸出finsh列印就已經結束了子執行緒了

# 多執行緒實現方式二,繼承thread 類,重寫run方法:

這是一種很基本的寫法。實際開發過程我們會涉及到類的呼叫以及類的方法引用寫法會發生改變:

這就意味著,我們需要根據實際場景使用不同的模組處理不同的需求,可以給大家乙個小提示可以使用concurrent.futures或者使用  queue.queue()來實現結果**,因為在queue原始碼中,它是基於deque來實現的而deque是執行緒安全的也就意味queue也是執行緒安全的,有興趣的可以自己去看下

j結語:

Python threading多執行緒

目錄1 2 lock encoding utf 8 import threading import time from queue import queue def thread 1 job print thread 1 start n for i in range 10 time.sleep 0....

Python threading(執行緒模組)

建立和使用方式基本和程序一致。有關執行緒的文字講述,請見 計算機 程序 執行緒 協程 import time from threading import thread,current thread,enumerate,active count def func i1,i2 i i1 i2 time....

簡述python(threading)多執行緒

一.概述 import threading 呼叫 t1 threading.thread target function args join 在子執行緒完成執行之前,這個子執行緒的父執行緒將一直被阻塞。setdaemon true 將執行緒宣告為守護執行緒,必須在start 方法呼叫之前設定,如果不...