深入理解 執行緒,程序,協程和並行,併發 協程

2022-04-20 08:52:29 字數 2811 閱讀 3628

爬蟲的併發控制:

多程序、多執行緒、協程 yield

從硬體:

雙核四執行緒(超執行緒技術):

有兩個cpu核心,每個核心有兩個邏輯處理器,相當於有四個cpu核心

四核四執行緒:

有乙個cpu核心,每個核心有乙個邏輯處理器,相當於有四個cpu核心

從作業系統:

程序和執行緒,都是cpu任務的執行單位。

程序:早期的作業系統是面向程序的:

表示乙個程式的執行活動(開啟、執行、儲存、關閉)

執行緒:現在的作業系統都是面向執行緒:

表示乙個程序處理任務時最小排程單位(執行功能a、執行功能b)

乙個程式至少開啟乙個程序,乙個程序至少有乙個執行緒。

每個程序都有獨立的記憶體空間,不同程序之間不共享任何狀態。

程序之間的通訊需要經過作業系統排程控制,通訊效率低、切換開銷大。

同乙個程序裡的多個執行緒,是共享記憶體空間,切換開銷小,通訊效率高。

執行緒的工作機制是"搶占式",出現競爭的狀態,競爭意味著資料不安全。

引入了"互斥鎖":讓多個執行緒安全有序的訪問記憶體空間的機制。

python的多執行緒:

類似於 gil(全域性直譯器鎖):保證乙個時間片裡只有乙個執行緒在執行。

好處:直接杜絕了多個執行緒的競爭問題:

壞處:python的多執行緒不是真正的多執行緒。

python直譯器在處理io阻塞型別的方法時,會釋放gil

如果沒有io操作,該執行緒會每隔 sys.getcheckinterval() 次釋放gil,讓其他執行緒嘗試執行。

並行:同一cpu時間片內,cpu可以同時處理多個程式。如果有多個程式,同步執行。

程式1:----------------

程式2:----------------

程式3:----------------

程式4:----------------

併發:同一cpu時間片,只能處理乙個程式。如果有多個程式,交替執行。

程式1: ----- ------

程式2: -----

程式3: ----

程式4: -----

多程序:可以充分利用多核cpu的資源,適用於密集cpu任務(大量的並行運算)

python的多程序模組:multiprocessing

程序之間通訊成本高切換開銷大,不適用於需要大量資料通訊和切換的任務(爬蟲)

設計模式:生產者消費者(並行模式)

多執行緒:適用於密集i/o任務(磁碟io,記憶體io,網路io),切換開銷小通訊成本低。

python的多執行緒:thread、thraeding、multiprocessing.dummy

多執行緒:同乙個時間片只能執行乙個執行緒,無法充分利用cpu多核資源(只能做到併發,不能做到並行)

協程:作業系統和cpu不認識協程,是由程式設計師通過**邏輯控制。

特點是在單執行緒下執行多個任務,且不需要通過作業系統切換(沒有切換開銷,也不需要處理鎖),執行效率高。

python: gevent ,猴子補丁(python**在執行網路io阻塞時,會自動切換協程)

協程:適用於密集網路i/o任務

多程序爬蟲:不合適

多執行緒爬蟲:缺點 - 通過作業系統排程,有執行緒切換開銷(海量urls場景會增加cpu負載);優點 - 使用場景廣泛(網路讀寫併發/資料庫讀寫併發/磁碟讀寫併發)

協程爬蟲:缺點 - gevent配合monkey.patch_all() 只能提高網路併發效率,不能處理其他併發場景;優點 - 通過程式設計師**邏輯控制,不受作業系統排程,沒有切換開銷,降低cpu負載(處理海量urls優勢明顯)

執行方式:

程式狀態:

阻塞:程式執行時,必須等待該任務完成,否則保持等待狀態。

非同步+非阻塞(效率最高):

傳送請求後,不必等待響應返回,可以繼續處理其他請求傳送;當處理功能掛起時,能夠立刻切換其他到功能繼續執行。

非同步網路框架 twisted tornada

scrapy :請求處理模組+響應解析模組+twisted

scrapy-redis:scrapy + redis(在同乙個資料庫裡處理請求去重、請求分配、資料儲存)

單機爬蟲:

分布式爬蟲:

cpu -> 暫存器 -> cpu快取l1/l2/l3 -> 記憶體 -> 硬碟/固態硬碟 -> 網路

協程:切換

三種方式實現:  1. yield   2.greenlet   3. gevent

1.yield

作用:掛起當前函式 將後面表示式的值 返回到呼叫生成器的地方

接收資料 並喚醒當前函式 並且緊接著上次執行的位址繼續執行

2.greenler

greenlet(函式)  建立協程

gr2.switch()切換到gr2執行

協程是python個中另外一種實現多工的方式,只不過比執行緒更小占用更小執行單元(理解為需要的資源)

通俗的理解:在乙個執行緒中的某個函式,可以在任何地方儲存當前函式的一些臨時變數等資訊,然後切換到另外乙個函式中執行,注意不是通過呼叫函式的方式做到的,並且切換的次數以及什麼時候再切換到原來的函式都由開發者自己確定

建立並執行協程

阻塞等待協程執行完成 .join()

阻塞等待所有協程退出 .join_all()

monkey.patch_all()作用是將rece, recefrom, time.sleep, accept進行破解, 不會阻塞等待, 在呼叫時可以切換到別的任務繼續執行.

注意:join,join_all作用保持主程序存活

簡單總結

程序 執行緒 協程理解

批處理 指乙個處理完了另乙個再處理 程序 即每個程式的執行的 全部流程 加上執行現場 當前執行場景 併發 因為多個程式在乙個cpu上不斷切換,人類看起來如同程式在同時執行,這就是併發 並行 即多個程式同時在多個cpu上執行,就是並行 執行緒 程序內部,有多個執行流程 加上每個流程的執行場景 這個流程...

深入理解非同步I O epoll 協程

同步和非同步的概念描述的是使用者執行緒與核心的互動方式 同步是指使用者執行緒發起io請求後需要等待或者輪詢核心io操作完成後才能繼續執行 而非同步是指使用者執行緒發起io請求後仍繼續執行,當核心io操作完成後會通知使用者執行緒,或者呼叫使用者執行緒註冊的 函式。阻塞和非阻塞的概念描述的是使用者執行緒...

簡單理解 程序 執行緒 協程

從計算機硬體角度 計算機的核心是cpu,所有計算任務都由cpu負責。單個cpu核心,在乙個cpu時間片裡,只能執行乙個程式任務。台式電腦 intel i5 處理器 四核四執行緒 四個cpu核心,每個核心有乙個邏輯處理器 同時可以處理四個任務。台式電腦 intel i7 處理器 四核八執行緒 inte...