io多路复用的原理和实现_IO多路复用的三种机制:select 、poll 、epoll
目錄
- 概述
- IO多路復用本質(zhì)
- IO多路復用的優(yōu)勢
- IO多路復用Select機制
- IO多路復用Poll機制
- IO多路復用Epoll機制
- select,poll,epoll機制區(qū)別總結(jié)
- php7進階到架構(gòu)師相關(guān)閱讀
概述
這是關(guān)于php進階到架構(gòu)之后端開發(fā)必備學習的第三篇文章:IO多路復用的三種機制:select 、poll 、epoll
- 第一篇:理解TCP/IP與UDP協(xié)議、Socket的正確姿勢
- 第二篇:一文搞懂進程,線程,CPU核心數(shù),時間片輪轉(zhuǎn)機制
- 第三篇:IO多路復用的三種機制:select 、poll 、epoll
IO多路復用本質(zhì)
檢測多個文件描述符是否有變化 。
讓單個進程可以監(jiān)視多個文件描述符,
一旦某個描述符就緒(一般是讀就緒或?qū)懢途w),
能夠通知程序進行相應(yīng)的讀寫操作
select,poll,epoll都是IO多路復用的機制。但select,poll,epoll本質(zhì)上都是同步I/O,因為他們都需要在讀寫事件就緒后自己負責進行讀寫,也就是說這個讀寫過程是阻塞的
IO多路復用的優(yōu)勢
與多進程和多線程技術(shù)相比,
I/O多路復用技術(shù)的最大優(yōu)勢是系統(tǒng)開銷小,
系統(tǒng)不必創(chuàng)建進程/線程,
也不必維護這些進程/線程,
從而大大減小了系統(tǒng)的開銷。
在介紹select、poll、epoll之前,首先介紹一下Linux操作系統(tǒng)中基礎(chǔ)的概念:
用戶空間 / 內(nèi)核空間
操作系統(tǒng)的核心是內(nèi)核,
獨立于普通的應(yīng)用程序,
可以訪問受保護的內(nèi)存空間,
也有訪問底層硬件設(shè)備的所有權(quán)限。
為了保證用戶進程(如qq,新浪等進程)不能直接操作內(nèi)核(kernel),保證內(nèi)核的安全,
操作系統(tǒng)將虛擬空間劃分為兩部分,
一部分為內(nèi)核空間,
一部分為用戶空間。
進程切換
為了控制進程的執(zhí)行,內(nèi)核必須有能力掛起正在CPU上運行的進程,并恢復以前掛起的某個進程的執(zhí)行。這種行為被稱為進程切換。
任何進程都是在操作系統(tǒng)內(nèi)核的支持下運行的,是與內(nèi)核緊密相關(guān)的,并且進程切換是非常耗費資源的。
進程阻塞
正在執(zhí)行的進程,由于期待的某些事件未發(fā)生,如請求系統(tǒng)資源失敗、等待某種操作的完成、新數(shù)據(jù)尚未到達或無新工作做等,則由系統(tǒng)自動執(zhí)行阻塞原語(Block),使進程由運行狀態(tài)變?yōu)樽枞麪顟B(tài)
只有處于運行態(tài)的進程(獲得了CPU資源),才可能將其轉(zhuǎn)為阻塞狀態(tài)。
當進程進入阻塞狀態(tài),是不占用CPU資源的。
文件描述符
文件描述符(File descriptor),是一個用于表述指向文件的引用的抽象化概念。
文件描述符在形式上是一個非負整數(shù)。
實際上,它是一個索引值,指向內(nèi)核為每一個進程所維護的該進程打開文件的記錄表。
當程序打開一個現(xiàn)有文件或者創(chuàng)建一個新文件時,內(nèi)核向進程返回一個文件描述符。
在程序設(shè)計中,一些涉及底層的程序編寫往往會圍繞著文件描述符展開。
但是文件描述符這一概念往往只適用于UNIX、Linux這樣的操作系統(tǒng)。
IO多路復用Select機制
select機制中提供一種fd_set的數(shù)據(jù)結(jié)構(gòu),實際上是一個long類型的數(shù)組。
每一個數(shù)組元素都能與一打開的文件句柄建立聯(lián)系,當調(diào)用select()時,由內(nèi)核根據(jù)IO狀態(tài)修改fd_set的內(nèi)容,由此來通知執(zhí)行了select()的進程哪一Socket或文件可讀。
select機制的問題
1.每次調(diào)用select,都需要把fd_set集合從用戶態(tài)拷貝到內(nèi)核態(tài),如果fd_set集合很大時,那這個開銷也很大
2.同時每次調(diào)用select都需要在內(nèi)核遍歷傳遞進來的所有fd_set,如果fd_set集合很大時,那這個開銷也很大
3.為了減少數(shù)據(jù)拷貝帶來的性能損壞,內(nèi)核對被監(jiān)控的fd_set集合大小做了限制,并且這個是通過宏控制的,大小不可改變(限制為1024)
IO多路復用Poll機制
poll改變了文件描述符集合的描述方式,
使用了pollfd結(jié)構(gòu)而不是select的fd_set結(jié)構(gòu),
使得poll支持的文件描述符集合限制遠大于select的1024
poll的機制與select類似,與select在本質(zhì)上沒有多大差別,管理多個描述符也是進行輪詢,根據(jù)描述符的狀態(tài)進行處理,但是poll沒有最大文件描述符數(shù)量的限制。
也就是說,poll只解決了上面select的問題3,并沒有解決問題1,2的性能開銷問題。
IO多路復用Epoll機制
epoll在Linux2.6內(nèi)核正式提出,是基于事件驅(qū)動的I/O方式。
相對于select來說,epoll沒有描述符個數(shù)限制,使用一個文件描述符管理多個描述符,將用戶關(guān)心的文件描述符的事件存放到內(nèi)核的一個事件表中,這樣在用戶空間和內(nèi)核空間的copy只需一次。
epoll是Linux內(nèi)核為處理大批量文件描述符而作了改進的poll,它能顯著提高程序在大量并發(fā)連接中只有少量活躍的情況下的系統(tǒng)CPU利用率。
原因就是獲取事件的時候,它無須遍歷整個被偵聽的描述符集,只要遍歷那些被內(nèi)核IO事件異步喚醒而加入Ready隊列的描述符集合就行了。
select,poll,epoll機制區(qū)別總結(jié)
epoll是Linux目前大規(guī)模網(wǎng)絡(luò)并發(fā)程序開發(fā)的首選模型。在絕大多數(shù)情況下性能遠超select和poll。
既然如此,為何select,poll,epoll同時存在呢?那是因為它們也是不同歷史時期的產(chǎn)物。
1984,在BSD實現(xiàn)select
1997,實現(xiàn)了poll
2002, 大神 Davide Libenzi 實現(xiàn)了epoll
php7進階到架構(gòu)師相關(guān)閱讀
https://www.kancloud.cn/gofor/gofor
最后,歡迎大家留言補充,討論~~~
總結(jié)
以上是生活随笔為你收集整理的io多路复用的原理和实现_IO多路复用的三种机制:select 、poll 、epoll的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 《无畏契约》国服要来了!腾讯WeGame
- 下一篇: 起亚正式进军中国电动汽车:争取7年后销量