io多路復用
參考書籍《後台開發 核心技術與應用實踐》《linux高效能伺服器程式設計》 《apue》之前嘮到了socket,嘮到了怎麼建立連線。
這篇文章就嘮一下,怎麼向socket中寫資料,怎麼從socket中讀出資料以及高效的讀寫----多路io復用技術
門口坐著瞅(阻塞)------(一直到)來了老弟------------辦事
呼叫者呼叫了某個函式,等待這個函式返回,期間什麼也不做,不停的去檢查這個函式有沒有返回,必須等這個函式返回才能進行下一步動作
瞅一下–瞅一下–瞅一下。。。。-----------來了老弟---------辦事
非阻塞等待,每隔一段時間就去檢測io事件是否就緒。沒有就緒就可以做其他事。非阻塞i/o執行系統呼叫總是立即返回,不管時間是否已經發生,若時間沒有發生,則返回-1,此時可以根據errno區分這兩種情況,對於accept,recv和send,事件未發生時,errno通常被設定成eagain
放個門鈴----來了老弟-----門鈴響了我聽到了-----辦事
linux用套介面進行訊號驅動io,安裝乙個訊號處理函式,程序繼續執行並不阻塞,當io時間就緒,程序收到sigio訊號。然後處理io事件。
emm,老鴇子僱了個秘書,你要啥服務跟我秘書說,你倆嘮完了再進來辦事
linux用select/poll函式實現io復用模型,這兩個函式也會使程序阻塞,但是和阻塞io所不同的是這兩個函式可以同時阻塞多個io操作。而且可以同時對多個讀操作、寫操作的io函式進行檢測。知道有資料可讀或可寫時,才真正呼叫io操作函式
就是我擱這開了個流水線服務,你要啥服務跟老鴇寫個條,然後等著就行了,然後等哪個師傅空了,老鴇把條給他。
**這裡的非同步與執行緒中的非同步不同!**非同步io主要表現的是由核心完成io之後,告知對應需求程式。
linux中,可以呼叫aio_read函式告訴核心描述字緩衝區指標和緩衝區的大小、檔案偏移及通知的方式,然後立即返回,當核心將資料拷貝到緩衝區後,再通知應用程式。
io多路復用其實這個詞翻譯過來直面意思會令人誤解。
簡單說來,在不用技巧的情況下。
client端連線進來,我肯定要判斷你有沒有給我發資訊。那麼我不能在這阻塞等你,我阻塞了我怎麼去再次呼叫accept。
所以我肯定是我server只負責去連線,然後給到乙個中間層幫我看著,是否client有東西發過來,如果發,再通知server。
那麼我們再想,listenfd,能不能被監控,就是說我也不傻傻的accept擱這等你了,我監控listenfd,有鏈結來。我直接accept,當場,啪一下我就返回了,很快啊。
我server就在這等你給我發通知就行了,你發lfd的通知 我就accept,你發資料到達的通知,我就讀唄。
於是這樣的思想,就誕生了 select,poll,epoll
這裡只通俗的介紹思想,具體使用參見man手冊select比較古老了,其實也就是之前我們說的,我要監控fd。
select最初的設計是維護了乙個陣列,這個陣列的max_size對應著當前系統能開啟檔案的最大個數(1024),也就是說select可監控fd有限。
考慮一種情況,我們如何判斷是否監控的fd上面有我感興趣的事情發生(連線,讀)。就是說我現在不是你server等了,我select等,如果事件來了,我就返回讓你處理,處理完,我再等。
ok,那麼下一步,我如何判斷哪個fd是發生事件的?
自然而然想到了遍歷,其實select也是這麼做的。通過遍歷來知道,哦原來是你小子給我擱這整事,然後通知server處理。
缺點:兩次拷貝耗時、輪詢所有fd耗時,支援的檔案描述符太小 優點:跨平台支援poll相較於select提公升不大,只不過他把事務細化了。並且學聰明了,你select陣列是吧,誒,我搞個鍊錶,我就長太多了。
所謂一寸長一寸強。
但是呢,由於你還是擱這老模式的一遍遍呼叫,沒什麼提公升效能。
優點:連線數(也就是檔案描述符)沒有限制(鍊錶儲存)epoll的年齡也沒有很大,相較於之前的兩個弟弟,epoll可以說是效能上的突飛猛進。缺點:大量拷貝,水平觸發(當報告了fd沒有被處理,會重複報告,很耗效能)
epoll的思想就是我這邊維護乙個當前已連線的fd的內容,用rbt實現。然後我返回的是已發生事件的fd的乙個總內容,sever只需要判斷返回的,至於樹上的,按需求來上還是下樹。
也就是epoll_ctl與epoll_wait
簡單說來,epoll就是為了實現在店面很大的情況下,有一部分人進店不幹事,擱這觀望。
ok,你觀望可以,去等候廳坐著吧,然後想好了,就去旁邊就緒廳排隊。
所以相對前兩個弟弟,epoll更符合現在的使用,因為我們無法判斷客戶什麼時候需求服務,可能他也就是連著,暫時還沒想好幹什麼而已。
優點:具體epoll的使用我會在之後的文章中對照講解1.沒有最大併發連線的限制
2.只有活躍可用的fd才會呼叫callback函式
3.記憶體拷貝是利用mmap()檔案對映記憶體的方式加速與核心空間的訊息傳遞,減少複製開銷。(核心與使用者空間共享一塊記憶體)
缺點:只有存在大量的空閒連線和不活躍的連線的時候,使用epoll的效率才會比select/poll高(這個褒貶不一吧,說服力沒那麼強,目前哪怕你再小型伺服器我也不用select?♂️)
《網路程式設計》I O 模型
在分析 i o 模型之前,首先了解 同步 i o 和 非同步 i o 的基本概念 同步 i o 程序呼叫 i o 操作函式時,在 i o 操作函式返回之前,該程序會被掛起 即阻塞 直到 i o 操作完成後返回 非同步 i o 程序呼叫 i o 操作函式時,在 i o 操作函式返回之前,該程序不會被掛...
Linux網路程式設計之IO模型
同步是指乙個任務的完成需要依賴另外乙個任務時,只有等待被依賴的任務完成後,依賴的任務才能算完成。非同步是指不需要等待被依賴的任務完成,只是通知被依賴的任務要完成什麼工作,依賴的任務也立即執行,只要自己完成了整個任務就算完成了,非同步一般使用狀態 通知和 阻塞是指呼叫結果返回之前,當前執行緒會被掛起,...
網路程式設計之IO模型 非同步IO
linux下的asynchronous io其實用得不多,從核心2.6版本才開始引入。先看一下它的流程 使用者程序發起read操作之後,立刻就可以開始去做其它的事。而另一方面,從kernel的角度,當它受到乙個asynchronous read之後,首先它會立刻返回,所以不會對使用者程序產生任何bl...