select、poll、epoll使用小结
轉(zhuǎn)載:http://blog.csdn.net/kkxgx/article/details/7717125
Linux上可以使用不同的I/O模型,我們可以通過下圖了解常用的I/O模型:同步和異步模型,以及阻塞和非阻塞模型,本文主要分析其中的異步阻塞模型。
一、select使用
這個模型中配置的是非阻塞I/O,然后使用阻塞select系統(tǒng)調(diào)用來確定一個I/O描述符何時有操作。使用select調(diào)用可以為多個描述符提供通知,對于每個提示符,我們可以請求描述符的可寫,可讀以及是否發(fā)生錯誤。異步阻塞I/O的系統(tǒng)流程如下圖所示:
使用select常用的幾個函數(shù)如下:
[cpp]?view plaincopy下面我們來看如何使用select:
[cpp]?view plaincopy
二、poll使用
poll函數(shù)類似于select,但是其調(diào)用形式不同。poll不是為每個條件構(gòu)造一個描述符集,而是構(gòu)造一個pollfd結(jié)構(gòu)體數(shù)組,每個數(shù)組元素指定一個描述符標號及其所關(guān)心的條件。定義如下:
[cpp]?view plaincopy每個結(jié)構(gòu)體的events域是由用戶來設置,告訴內(nèi)核我們關(guān)注的是什么,而revents域是返回時內(nèi)核設置的,以說明對該描述符發(fā)生了什么事件。這點與select不同,select修改其參數(shù)以指示哪一個描述符準備好了。在《unix環(huán)境高級編程》中有一張events取值的表,如下:
POLLIN :可讀除高優(yōu)級外的數(shù)據(jù),不阻塞
POLLRDNORM:可讀普通數(shù)據(jù),不阻塞
POLLRDBAND:可讀O優(yōu)先數(shù)據(jù),不阻塞
POLLPRI:可讀高優(yōu)先數(shù)據(jù),不阻塞
POLLOUT :可寫普數(shù)據(jù),不阻塞
POLLWRNORM:與POLLOUT相同
POLLWRBAND:寫非0優(yōu)先數(shù)據(jù),不阻塞
其次revents還有下面取值
POLLERR :已出錯
POLLHUP:已掛起,當以描述符被掛起后,就不能再寫向該描述符,但是仍可以從該描述符讀取到數(shù)據(jù)。
POLLNVAL:此描述符并不引用一打開文件
對poll函數(shù),nfds表示fds中的元素數(shù),timeout為超時設置,單位為毫秒若為0,表示不等待,為-1表示描述符中一個已經(jīng)準備好或捕捉到一個信號返回,大于0表示描述符準備好,或超時返回。函數(shù)返回值返回值若為0,表示沒有事件發(fā)生,-1表示錯誤,并設置errno,大于0表示有幾個描述符有事件。
poll的使用和select基本類似。在此不再介紹。poll相對于是select的優(yōu)勢是監(jiān)聽的描述符數(shù)量沒有限制。
三、epoll學習
epoll有兩種模式,Edge Triggered(簡稱ET) 和 Level Triggered(簡稱LT).在采用這兩種模式時要注意的是,如果采用ET模式,那么僅當狀態(tài)發(fā)生變化時才會通知,而采用LT模式類似于原來的select/poll操作,只要還有沒有處理的事件就會一直通知.
1)epoll數(shù)據(jù)結(jié)構(gòu)介紹:
[cpp]?view plaincopyEPOLLIN:表示對描述符的可以讀
EPOLLOUT:表示對描述符的可以寫
EPOLLPRI:表示對描述符的有緊急數(shù)據(jù)可以讀
EPOLLERR:發(fā)生錯誤
EPOLLHUP:掛起
EPOLLET:邊緣觸發(fā)
EPOLLONESHOT:一次性使用,當監(jiān)聽完這次事件之后,如果還需要繼續(xù)監(jiān)聽這個socket的話,需要再次把這個socket加入到EPOLL隊列里
2)函數(shù)介紹
epoll的三個函數(shù)
[cpp]?view plaincopy參數(shù):size為epoll上能關(guān)注的最大描述符數(shù)
[cpp]?view plaincopy參數(shù):epfd由epoll_create生成的epoll專用描述符
? ? op操作:EPOLL_CTL_ADD 注冊 ? EPOLL_CTL_MOD修改 ?EPOLL_DEL刪除
? ? ? ? ? ? fd:關(guān)聯(lián)的文件描述符
? ? evnet告訴內(nèi)核要監(jiān)聽什么事件
[cpp]?view plaincopy參數(shù):epfd要檢測的句柄
? ? ?events:用于回傳待處理時間的數(shù)組
? ? ?maxevents:告訴內(nèi)核這個events有多大,不能超過之前的size
? ? ?timeout:為超時時間
使用方法參考:https://banu.com/blog/2/how-to-use-epoll-a-complete-example-in-c/epoll-example.c
epoll支持的FD上限是最大可以打開文件的數(shù)目(select面臨這樣的問題),IO效率不隨FD數(shù)目增加而線性下降(select、poll面臨的問題)使用mmap加速內(nèi)核與用戶空間的消息傳遞。現(xiàn)在libevent封裝了幾種的實現(xiàn),可以通過使用libevent來實現(xiàn)多路復用。
?本文參考:https://banu.com/blog/2/how-to-use-epoll-a-complete-example-in-c/
? ?http://www.ibm.com/developerworks/cn/linux/l-cn-edntwk/index.html?ca=drs-
? ? ? ? ? ? ?http://www.ibm.com/developerworks/cn/linux/l-async/
總結(jié)
以上是生活随笔為你收集整理的select、poll、epoll使用小结的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Linux select 实现并发服务器
- 下一篇: inet_pton, inet_ntop