11、協程和io教程01 -- 併發 並行 同步 非同步 阻塞 非阻塞 以及 IO多路複用

鞍-發表於2020-11-13

01、協程預先鋪墊

--協程這一章比執行緒更加複雜,需要和socket那兩章混合起來學習學習

02、併發 並行

--併發:一個時間段內【不是一個時間點】,執行多個程式。但是每一時刻cpu中只能有一個程式在執行,那麼這些執行的程式就是處於併發狀態的。

--並行:同一時刻,多個程式碼同時執行在多個cpu上,程式碼處於並行狀態

03、同步 非同步

--同步:當出現IO操作時,必須等待IO操作返回時才繼續執行的操作稱為同步。不涉及到IO操作時不需要考慮是否同步

--非同步:不需要等待IO操作執行完畢返回結果,即可往下執行程式稱之為非同步操作。
    --多執行緒就是典型的非同步操作,它在啟動之後直接能夠得到一個返回物件

--這裡的IO操作需要學習作業系統之後才能理解,不能簡單視為存取檔案。像爬蟲 || 向伺服器發請求  || 呼叫某個部署好的程式等都可以視為IO操作

04、阻塞 非阻塞

--阻塞:呼叫函式時,當前程式被掛起。比如我們呼叫多執行緒是通過阻塞的方式,使得我們在接收到結果時才繼續執行當前程式,但是多執行緒時非同步的。也就是說不論是同步還是非同步方式執行程式,都不會影響我們阻塞當前程式

--非阻塞:呼叫函式時當前執行緒不被掛起,繼續執行。同樣也和同步非同步關係不大

05、同步 非同步 與 阻塞 非阻塞 的辨別

--同步 非同步 可以視為一種訊息通訊機制

--阻塞 非阻塞 可以視為一種函式呼叫機制

06、IO多路複用 -- c10k問題

--如何讓一臺 1Ghz cpu | 2G記憶體 | 1gbps網路環境下 的伺服器同時為1萬個客戶同時提供FTP服務
    --顯然使用1萬個執行緒是不合乎現實情況的,伺服器會崩潰掉

    --這裡就需要借用:同步非同步 阻塞非阻塞 併發 io多路複用等方法混合使用解決該問題
    

07、unix下的5中I/O模型

--阻塞式IO:最基本的,也是程式設計中經常涉及到的

--非阻塞式IO:進一步講解socket程式設計時會講解到

--IO多路複用:

--訊號驅動式IO:使用極少,不講

--非同步IO (POSIX的aio_系列函式):

--阻塞式IO圖解說明:引用自 unix網路程式設計,recvfrom表示呼叫IO介面資源,並獲取資料

--阻塞式IO儘管程式設計非常順利,但是浪費了大量的cpu等待時間,效率低下

--非阻塞式IO圖解說明:

--非阻塞式IO:如果後續程式碼依賴於前面程式碼的執行,此使非阻塞式IO需要等待前面程式碼執行完畢。此使效率甚至不如阻塞式IO方式,
例如在socket連線時,建立連線三次握手需要時間,即使沒有阻塞也需要判斷是否連線建立成功。因此無法直接繼續執行程式碼

--對於核心 和 APP記憶體使用的注意:
    --核心自己的記憶體[更加底層] 和 APP執行時申請的記憶體不是一個
    --核心的記憶體是不能夠讓APP直接訪問的
    --web返回資料先儲存在核心記憶體,之後由核心記憶體拷貝一份給需要使用的APP

--非阻塞式IO可能出現輪詢查IO資料獲取的狀態情況,為了能夠節約cpu資源,讓資料返回到核心記憶體中後系統自己主動告訴程式資料準備好了,以避免對cpu資源的浪費。這裡就出現了io多路複用

--IO多路複用:實際就是涉及這三個函式 -- select  poll  epoll

--select函式:查詢核心記憶體中是否拿到了返回的響應資料
    --select函式是阻塞的,如果核心中沒有一個socket或檔案控制程式碼準備好時,socket實際上會一直阻塞在這裡
      通過以上可以看出 IO多路複用 被歸結於 非阻塞式 是不正確的
    --注:這個和輪詢查詢狀態不一樣,select可以監聽多個socket和檔案控制程式碼,一旦有某一個已準備完畢即刻會被返回。有了這樣一種屬性,select就可以實現高併發而輪詢是做不到的
    --select通過監聽多個socket和檔案控制程式碼實現併發,但是對於從核心記憶體中複製資料到APP記憶體這一段路來說仍然無法避免時間消耗 

--訊號驅動式IO:這種方式使用極少,可以不做了解

--非同步IO:這個才是真正意義上的非同步,但是很多非同步框架使用的還是IO多路複用技術,非同步IO相對而言不夠技術成熟

--aio_read:相對於select函式節省了核心記憶體複製到APP記憶體的時間

相關文章