Python的 併發、並行
記錄:
併發:在一個時間段,處理多個任務,單核也可以併發(CPU分時間片);
並行:在同一個時刻,處理多個任務,必須多核才能並行;
一、Python實現併發的手段:
1、作業系統提供:程式、執行緒;
2、程式語言提供:協程:使用者空間的排程(py3);
題外話:
現在的作業系統,程式和執行緒的區別越來越小,因為程式越來越輕了;實際上,Linux的執行緒是通過程式實現的;
二、Python的程式和執行緒的區別:
Python每個程式都會啟動一個直譯器;
Python每個執行緒(一個程式下面的)共享一個直譯器;
ps:Python沒有提供主動停止執行緒的方法的;只能等執行緒處理完畢,或者主執行緒結束;所以線上程邏輯裡面一定要寫退出邏輯;
三、logging庫:
通常用logging代替print,因為logging是執行緒安全的,在多執行緒下,輸出表現正常,而print是非執行緒安全的,在多執行緒下,輸出表現會出現異常,例如,T1沒輸出完畢,T2又進行輸出了;
四、Python 執行緒的 daemon 屬性:
預設是false;
daemon:守護、守護程式;
守護程式:Daemon()程式是一直執行的服務端程式,又稱為守護程式。通常在系統後臺執行,沒有控制終端,不與前臺互動,Daemon程式一般作為系統服務使用。Daemon是長時間執行的程式,通常在系統啟動後就執行,在系統關閉時才結束。
知識點一:
當一個程式啟動之後,會預設產生一個主執行緒,因為執行緒是程式執行流的最小單元,當設定多執行緒時,主執行緒會建立多個子執行緒,在python中,預設情況下(其實就是setDaemon(False)),主執行緒執行完自己的任務以後,就退出了,此時子執行緒會繼續執行自己的任務,直到自己的任務結束;
知識點二:
當我們使用setDaemon(True)方法,設定子執行緒為守護執行緒時,主執行緒一旦執行結束,則全部執行緒全部被終止執行,可能出現的情況就是,子執行緒的任務還沒有完全執行結束,就被迫停止;
知識點三:
join所完成的工作就是執行緒同步,即主執行緒任務結束之後,進入阻塞(等待)狀態,一直等待其他的子執行緒執行結束之後,主執行緒在終止;
知識點四:
join有一個timeout引數:
當設定守護執行緒時,含義是主執行緒對於子執行緒等待timeout的時間將會殺死該子執行緒,最後退出程式。所以說,如果有10個子執行緒,全部的等待時間就是每個timeout的累加和。簡單的來說,就是給每個子執行緒一個timeout的時間,讓他去執行,時間一到,不管任務有沒有完成,直接殺死。
沒有設定守護執行緒時,主執行緒將會等待timeout的累加和這樣的一段時間,時間一到,主執行緒結束,但是並沒有殺死子執行緒,子執行緒依然可以繼續執行,直到子執行緒全部結束,程式退出。
t1.join(),子執行緒設定這個就是讓主執行緒阻塞(等待),那麼在哪裡設定了 t1.join(),主執行緒就在這裡等待t1執行完畢,再繼續往下執行;因為兩個執行緒順序完成,看起來象一個執行緒,所以稱為執行緒的合併,其實也是讓執行緒同步了;
注意(看到的結果是這樣,解釋可能不太正確):
(1)看圖:
t1設定執行2秒;t2設定執行3秒;目的是為了t1先於t2執行完畢;
t1沒有設定daemon執行緒,所以當主執行緒結束後,t1仍然會繼續執行完畢,所以檢視結果:當輸出 main end ... 後,仍然有 t1 out ... 輸出;
t2設定為daemon執行緒,所以當主執行緒結束後,t2也被主執行緒殺死了(t1已結執行完畢),跟著結束了,程式(程式)也結束了,所以沒有 t2 out... 輸出;
注意,這裡一定要保證t1(非daemon子執行緒)先於t2執行完畢;因為如果t1要比t2耗時長的話,因為 t1是非daemon子執行緒,即是主執行緒結束了,t1仍然要繼續執行的,所以整個程式(程式)並不會結束,也就沒有殺死t2,導致t2也會執行完畢;看下面:
可以看到:即是t2是daemon子執行緒,但是仍然執行完畢了,並沒有因為主執行緒的退出而被殺死,因為t1的執行時間比t2長;
ps:如果不是以繼承的方式建立執行緒,那麼run方法和start方法只能執行其中一個;通常也不建議使用繼承的方式;start方法是子執行緒執行的,啟動子執行緒;
要注意:主執行緒、父執行緒、子執行緒的關係;
五、Python中的ThreadLocal變數
注意,並不是子執行緒要執行的目標函式裡面的區域性變數,雖然每個執行緒即使是執行同一個函式,都會有自己的記憶體的,互不干擾,但是函式裡面的區域性變數,就是屬於函式的,到了另外一個函式不會認識此區域性變數;
而Python的threadlocal變數,是屬於執行緒的,此執行緒呼叫的所有函式都認識threadlocal變數,eg.:
global_data = threading.local()
def show():
print (threading.current_thread().getName(), global_data.num)
def thread_cal():
global_data.num = 0
for _ in xrange(1000):
global_data.num += 1
show()
每個執行緒都可以通過 global_data.num 獲得自己獨有的資料,並且每個執行緒讀取到的 global_data 都不同,真正做到執行緒之間的隔離。其他執行緒是不認識global_data.num的;
六、執行緒同步方式(前三個方式需要在具體瞭解)
執行緒的同步,有一層意思就是:執行緒之間的通訊,執行緒總是有某種關聯,才需要同步的,而同步就意味著阻塞(等待);
1、event
兩個執行緒之間事件的通知,我發現了一個事件,set,你就可以檢視。
2、lock (rlock?)
保護共享資源;
3、condition
生產者消費者模式;生產者喚醒消費者;
4、Barrier(柵欄)
就是執行緒們在等待,直到執行緒數滿足設定的數量之和,才繼續執行;
可以使用此方法開發併發測試工具;
一些關鍵語句:
barrier = threading.Barrier(3) #等齊3個執行緒
worker_id = barrier.wait() #執行緒執行到這一句,就等著,滿足數量之後,再往下走
barrier.n_waiting #現在在等待的執行緒數量
barrier.abort() #通知已經在等待的執行緒,不必再等了,我執行不到wait()了(任何一個執行緒執行都可以),當abort()方法被執行,wait()方法就會丟擲異常
5、semaphore (訊號量)
s = threading.Semaphore(2)
s.acquire() # 獲得,線上程中,也是鎖住某個變數,自己此刻獨佔;
輸出:True # 成功鎖住
s.acquire(False) # 再來一次
輸出:True # 成功鎖住
s.acquire(False) # 再來一次
輸出:False # 沒有鎖
鎖是訊號量的特例:為1的訊號量;
訊號量也是對共享資源的保護,但是和鎖不一樣,鎖限制只有一個執行緒可以訪問共享資源,而訊號量限制指定個執行緒可以訪問共享資源;所以訊號量可以用於做連線池的功能;
七、非同步程式設計
1、概念
同步、非同步:
發生在函式呼叫的時候,是否得到直接最終結果;
得到直接最終結果的是:同步呼叫;
不得到直接最終結果的是:非同步呼叫;
阻塞、非阻塞:
發生在函式呼叫的時候,是否立刻返回;
立刻返回:非阻塞呼叫;
不立刻返回:阻塞呼叫;
ps:同步、非同步 與 阻塞、非阻塞 在概念上是不相關的;
同步、非同步:關注的是結果;
阻塞、非阻塞:關注的是是否等待;
ps:非同步非阻塞是最好的效能咯;
同步IO、非同步IO、IO多路複用:
相關文章
- Python併發與並行的新手指南Python並行
- Java併發(一)----程式、執行緒、並行、併發Java執行緒並行
- 快速理解併發、並行並行
- [Java併發]執行緒的並行等待Java執行緒並行
- 併發不是並行 它更好!並行
- 執行緒 並行 與 併發 的區別執行緒並行
- 架構之:併發和並行架構並行
- 深入理解併發和並行並行
- 全網最適合入門的物件導向程式設計教程:59 Python並行與併發-並行與併發和執行緒與程序物件程式設計Python並行執行緒
- Java多執行緒--併發和並行的區別Java執行緒並行
- 並行化-你的高併發大殺器並行
- 並行和併發的區別與聯絡並行
- java多執行緒詳解(併發,並行,同步)Java執行緒並行
- .NET併發程式設計-資料並行程式設計並行
- 我已經理解了併發和並行的區別並行
- 吃個快餐都能學到序列、並行、併發並行
- 【作業系統】3.併發和並行作業系統並行
- 【python高併發】程序、執行緒的理解Python執行緒
- 併發程式設計-8.並行資料結構和並行Linq程式設計並行資料結構
- Golang非CSP併發模型外的其他並行方法總結Golang模型並行
- 程式執行緒、同步非同步、阻塞非阻塞、併發並行執行緒非同步並行
- python併發執行request請求Python
- .NET併發程式設計-任務函式並行程式設計函式並行
- 執行緒,程式,協程, 併發,並行,同步,非同步概念解析執行緒並行非同步
- 【OS】同步非同步/阻塞非阻塞、併發並行序列的區分非同步並行
- Python《多執行緒併發爬蟲》Python執行緒爬蟲
- 使用Python進行併發程式設計Python程式設計
- 圖解併發與並行-分別從CPU和執行緒的角度理解圖解並行執行緒
- .NET併發程式設計-TPL Dataflow並行工作流程式設計並行
- ♻️同步和非同步;並行和併發;阻塞和非阻塞非同步並行
- Python多執行緒併發的簡單測試Python執行緒
- Nginx 高階篇(十)並行 併發 單執行緒(廢話篇 )Nginx並行執行緒
- python基礎執行緒-管理併發執行緒Python執行緒
- 超越執行緒池:Java併發並沒有你想的那麼糟糕執行緒Java
- 透過一個示例形象地理解C# async await 非並行非同步、並行非同步、並行非同步的併發量控制C#AI並行非同步
- python+selenium grid 併發執行測試用例,不能併發Python
- 聊聊 Jmeter 如何併發執行 Python 指令碼JMeterPython指令碼
- goroutine併發執行多個任務並依次返回結果Go