select嫡纠、poll烦租、epoll之間的區(qū)別總結(jié)[整理](轉(zhuǎn)載)

寫在前面

轉(zhuǎn)載自: Anker—工作學(xué)習(xí)筆記
參考文章: select、poll除盏、epoll之間的區(qū)別總結(jié)[整理]


select叉橱,poll,epoll都是IO多路復(fù)用的機(jī)制者蠕。I/O多路復(fù)用就通過一種機(jī)制窃祝,可以監(jiān)視多個描述符,一旦某個描述符就緒(一般是讀就緒或者寫就緒)踱侣,能夠通知程序進(jìn)行相應(yīng)的讀寫操作粪小。select,poll抡句,epoll本質(zhì)上都是同步I/O探膊,因為他們都需要在讀寫事件就緒后自己負(fù)責(zé)進(jìn)行讀寫,也就是說這個讀寫過程是阻塞的待榔,而異步I/O則無需自己負(fù)責(zé)進(jìn)行讀寫逞壁,異步I/O的實(shí)現(xiàn)會負(fù)責(zé)把數(shù)據(jù)從內(nèi)核拷貝到用戶空間。關(guān)于這三種IO多路復(fù)用的用法锐锣,前面三篇總結(jié)寫的很清楚腌闯,并用服務(wù)器回射echo程序進(jìn)行了測試。鏈接如下:

select參考
poll參考
epoll參考

今天對這三種IO多路復(fù)用進(jìn)行對比刺下,參考網(wǎng)上和書上面的資料绑嘹,整理如下:

1. select實(shí)現(xiàn)

select的調(diào)用過程如下所示:

select

[過程]
(1)使用copy_from_user從用戶空間拷貝fd_set到內(nèi)核空間
(2)注冊回調(diào)函數(shù)__pollwait
(3)遍歷所有fd,調(diào)用其對應(yīng)的poll方法(對于socket橘茉,這個poll方法是sock_pollsock_poll根據(jù)情況會調(diào)用到tcp_poll,udp_poll或者datagram_poll
(4)以tcp_poll為例姨丈,其核心實(shí)現(xiàn)就是__pollwait畅卓,也就是上面注冊的回調(diào)函數(shù)。
(5)__pollwait的主要工作就是把current(當(dāng)前進(jìn)程)掛到設(shè)備的等待隊列中蟋恬,不同的設(shè)備有不同的等待隊列翁潘,對于tcp_poll來說,其等待隊列是sk->sk_sleep(注意把進(jìn)程掛到等待隊列中并不代表進(jìn)程已經(jīng)睡眠了)歼争。在設(shè)備收到一條消息(網(wǎng)絡(luò)設(shè)備)或填寫完文件數(shù)據(jù)(磁盤設(shè)備)后拜马,會喚醒設(shè)備等待隊列上睡眠的進(jìn)程渗勘,這時current便被喚醒了。
(6)poll方法返回時會返回一個描述讀寫操作是否就緒的mask掩碼俩莽,根據(jù)這個mask掩碼給fd_set賦值旺坠。
(7)如果遍歷完所有的fd,還沒有返回一個可讀寫的mask掩碼扮超,則會調(diào)用schedule_timeout是調(diào)用select的進(jìn)程(也就是current)進(jìn)入睡眠取刃。當(dāng)設(shè)備驅(qū)動發(fā)生自身資源可讀寫后,會喚醒其等待隊列上睡眠的進(jìn)程出刷。如果超過一定的超時時間(schedule_timeout指定)璧疗,還是沒人喚醒,則調(diào)用select的進(jìn)程會重新被喚醒獲得CPU馁龟,進(jìn)而重新遍歷fd崩侠,判斷有沒有就緒的fd
(8)把fd_set從內(nèi)核空間拷貝到用戶空間坷檩。

總結(jié):
select的幾大缺點(diǎn):
(1)每次調(diào)用select啦膜,都需要把fd集合從用戶態(tài)拷貝到內(nèi)核態(tài),這個開銷在fd很多時會很大
(2)同時每次調(diào)用select都需要在內(nèi)核遍歷傳遞進(jìn)來的所有fd淌喻,這個開銷在fd很多時也很大
(3)select支持的文件描述符數(shù)量太小了僧家,默認(rèn)是1024

2. poll實(shí)現(xiàn)

poll的實(shí)現(xiàn)和select非常相似,只是描述fd集合的方式不同裸删,poll使用pollfd結(jié)構(gòu)而不是selectfd_set結(jié)構(gòu)八拱,其他的都差不多。

關(guān)于select和poll的實(shí)現(xiàn)分析涯塔,可以參考下面幾篇博文:
http://blog.csdn.net/lizhiguo0532/article/details/6568964#comments
http://blog.csdn.net/lizhiguo0532/article/details/6568968
http://blog.csdn.net/lizhiguo0532/article/details/6568969
http://www.ibm.com/developerworks/cn/linux/l-cn-edntwk/index.html?ca=drs-
http://linux.chinaunix.net/techdoc/net/2009/05/03/1109887.shtml

3. epoll

epoll既然是對selectpoll的改進(jìn)肌稻,就應(yīng)該能避免上述的三個缺點(diǎn)。那epoll都是怎么解決的呢匕荸?在此之前爹谭,我們先看一下epollselectpoll的調(diào)用接口上的不同,selectpoll都只提供了一個函數(shù)——select或者poll函數(shù)榛搔。而epoll提供了三個函數(shù):epoll_create,epoll_ctl 和 epoll_wait诺凡,epoll_create是創(chuàng)建一個epoll句柄;epoll_ctl是注冊要監(jiān)聽的事件類型践惑;epoll_wait則是等待事件的產(chǎn)生腹泌。

對于第一個缺點(diǎn)epoll的解決方案在epoll_ctl函數(shù)中:每次注冊新的事件到epoll句柄中時(在epoll_ctl中指定EPOLL_CTL_ADD)尔觉,會把所有的fd拷貝進(jìn)內(nèi)核凉袱,而不是在epoll_wait的時候重復(fù)拷貝。epoll保證了每個fd在整個過程中只會拷貝一次。

對于第二個缺點(diǎn)专甩,epoll的解決方案不像selectpoll一樣每次都把current輪流加入fd對應(yīng)的設(shè)備等待隊列中钟鸵,而只在epoll_ctl時把current掛一遍(這一遍必不可少)并為每個fd指定一個回調(diào)函數(shù),當(dāng)設(shè)備就緒涤躲,喚醒等待隊列上的等待者時棺耍,就會調(diào)用這個回調(diào)函數(shù),而這個回調(diào)函數(shù)會把就緒的fd加入一個就緒鏈表)篓叶。epoll_wait的工作實(shí)際上就是在這個就緒鏈表中查看有沒有就緒的fd(利用schedule_timeout()實(shí)現(xiàn)睡一會烈掠,判斷一會的效果,和select實(shí)現(xiàn)中的第7步是類似的)缸托。

對于第三個缺點(diǎn)左敌,epoll沒有這個限制,它所支持的FD上限是最大可以打開文件的數(shù)目俐镐,這個數(shù)字一般遠(yuǎn)大于2048,舉個例子:在1GB內(nèi)存的機(jī)器上大約是10萬左右矫限,具體數(shù)目可以cat /proc/sys/fs/file-max察看,一般來說這個數(shù)目和系統(tǒng)內(nèi)存關(guān)系很大。

總結(jié):
(1)select佩抹,poll實(shí)現(xiàn)需要自己不斷輪詢所有fd集合叼风,直到設(shè)備就緒,期間可能要睡眠和喚醒多次交替棍苹。而epoll其實(shí)也需要調(diào)用epoll_wait不斷輪詢就緒鏈表无宿,期間也可能多次睡眠和喚醒交替,但是它是設(shè)備就緒時枢里,調(diào)用回調(diào)函數(shù)孽鸡,把就緒fd放入就緒鏈表中,并喚醒在epoll_wait中進(jìn)入睡眠的進(jìn)程栏豺。雖然都要睡眠和交替彬碱,但是select和poll在“醒著”的時候要遍歷整個fd集合,而epoll在“醒著”的時候只要判斷一下就緒鏈表是否為空就行了奥洼,這節(jié)省了大量的CPU時間巷疼。這就是回調(diào)機(jī)制帶來的性能提升。
(2)select灵奖,poll每次調(diào)用都要把fd集合從用戶態(tài)往內(nèi)核態(tài)拷貝一次嚼沿,并且要把current往設(shè)備等待隊列中掛一次,而epoll只要一次拷貝桑寨,而且把current往等待隊列上掛也只掛一次(在epoll_wait的開始伏尼,注意這里的等待隊列并不是設(shè)備等待隊列,只是一個epoll內(nèi)部定義的等待隊列)尉尾。這也能節(jié)省不少的開銷。

參考資料:
http://www.cnblogs.com/apprentice89/archive/2013/05/09/3070051.html
http://www.linuxidc.com/Linux/2012-05/59873p3.htm
http://xingyunbaijunwei.blog.163.com/blog/static/76538067201241685556302/
http://blog.csdn.net/kkxgx/article/details/7717125
https://banu.com/blog/2/how-to-use-epoll-a-complete-example-in-c/epoll-example.c

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末燥透,一起剝皮案震驚了整個濱河市沙咏,隨后出現(xiàn)的幾起案子辨图,更是在濱河造成了極大的恐慌,老刑警劉巖肢藐,帶你破解...
    沈念sama閱讀 218,755評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件故河,死亡現(xiàn)場離奇詭異,居然都是意外死亡吆豹,警方通過查閱死者的電腦和手機(jī)鱼的,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,305評論 3 395
  • 文/潘曉璐 我一進(jìn)店門燥滑,熙熙樓的掌柜王于貴愁眉苦臉地迎上來颖系,“玉大人,你說我怎么就攤上這事芬萍≈钥欤” “怎么了宙橱?”我有些...
    開封第一講書人閱讀 165,138評論 0 355
  • 文/不壞的土叔 我叫張陵,是天一觀的道長蘸拔。 經(jīng)常有香客問我师郑,道長,這世上最難降的妖魔是什么调窍? 我笑而不...
    開封第一講書人閱讀 58,791評論 1 295
  • 正文 為了忘掉前任宝冕,我火速辦了婚禮,結(jié)果婚禮上邓萨,老公的妹妹穿的比我還像新娘地梨。我一直安慰自己,他們只是感情好先誉,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,794評論 6 392
  • 文/花漫 我一把揭開白布湿刽。 她就那樣靜靜地躺著,像睡著了一般褐耳。 火紅的嫁衣襯著肌膚如雪诈闺。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,631評論 1 305
  • 那天铃芦,我揣著相機(jī)與錄音雅镊,去河邊找鬼。 笑死刃滓,一個胖子當(dāng)著我的面吹牛仁烹,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播咧虎,決...
    沈念sama閱讀 40,362評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼卓缰,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起征唬,我...
    開封第一講書人閱讀 39,264評論 0 276
  • 序言:老撾萬榮一對情侶失蹤捌显,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后总寒,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體扶歪,經(jīng)...
    沈念sama閱讀 45,724評論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,900評論 3 336
  • 正文 我和宋清朗相戀三年摄闸,在試婚紗的時候發(fā)現(xiàn)自己被綠了善镰。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,040評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡年枕,死狀恐怖炫欺,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情画切,我是刑警寧澤竣稽,帶...
    沈念sama閱讀 35,742評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站霍弹,受9級特大地震影響毫别,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜典格,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,364評論 3 330
  • 文/蒙蒙 一岛宦、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧耍缴,春花似錦砾肺、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,944評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至蚁趁,卻和暖如春裙盾,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背他嫡。 一陣腳步聲響...
    開封第一講書人閱讀 33,060評論 1 270
  • 我被黑心中介騙來泰國打工番官, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人钢属。 一個月前我還...
    沈念sama閱讀 48,247評論 3 371
  • 正文 我出身青樓徘熔,卻偏偏與公主長得像,于是被迫代替她去往敵國和親淆党。 傳聞我的和親對象是個殘疾皇子酷师,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,979評論 2 355

推薦閱讀更多精彩內(nèi)容