對IO多路復(fù)用三種機制(select,poll,epoll)的理解

1.select

? ? 1.1函數(shù)原型:

????????????int select(int maxfdp1, fd_set *readset,fd_set *writeset,fd_set *exceptset,const struct timeval *timeout);

????1.2參數(shù)說明:

? ? ? ? ? ? ?int maxfdp1:指定待測試文件描述字個數(shù),值是待測最大文件描述符+1.

? ? ? ? ? ? ?fd_set *readset,fd_set *writeset,fd_set *exceptset:fd_set一個集合,這個集合存放的是文件描述符,讀 寫 異常條件的文件描述符集合,若對某一個條件不感興趣,置為NULL即可。

????????????const struct timeval *timeout:超時時間,告訴內(nèi)核等待指定文件描述符集合中任何一個就行花費的時間。? ? ? ? ? ??

????1.3運行機制:

? ? ? ? ?提供一種fd_set的數(shù)據(jù)結(jié)構(gòu),實際上是一個long型的數(shù)組,每一個數(shù)組元素都與一個打開的文件句柄建立聯(lián)系;調(diào)用select時,內(nèi)核根據(jù)IO狀態(tài)修改fd的內(nèi)容,通知執(zhí)行select的進程哪一個socket或者文件可讀。 ? ? ? ??

????1.4優(yōu)點:

? ? ? ? ?select函數(shù)進行IO請求和同步阻塞模型沒有太大的區(qū)別。其優(yōu)點是在一個線程內(nèi)同時處理多個socket的IO請求,而同步阻塞模型中,必須通過多線程的方式才能達到這個目的。?? ??????????????

????1.5缺陷: ? ?

? ? ? ? ? 每次調(diào)用select,都需要把fd從用戶態(tài)拷貝到內(nèi)核態(tài),如果fd集合很大時,這個開銷也很大;每次調(diào)用select都要在內(nèi)核中遍歷傳來的所有fd_set,沒有事件的也要被遍歷,做了許多無用功,為了減少數(shù)據(jù)拷貝帶來的性能損害,內(nèi)核對被監(jiān)控的fd集合大小做了限制,為1024,不可改變。

2.poll????

? ??1.1函數(shù)原型:

? ? ? ? ? ? int poll(struct pollfd *fds, nfds_t nfds, int timeout);

? ? 1.2參數(shù)說明:

? ? ? ?struct pollfd *fds:pollfd類型的數(shù)組,存放需要檢測狀態(tài)的socket描述符,調(diào)用poll之后fds數(shù)組不會被清空;一個結(jié)構(gòu)體表示一個被監(jiān)視的文件描述符,結(jié)構(gòu)體events表示監(jiān)視文件描述符的事件掩碼,revents表示文件描述符操作結(jié)果的事件掩碼,內(nèi)核調(diào)用時返回設(shè)置這個域。

? ? ? ? nfds 記錄數(shù)組fds中描述符的總數(shù)量

? ? ? ? 返回值為fds集合中讀寫或出錯的描述符數(shù)量,0表示超時-1表示出錯。

????1.3運行機制:

? ? ? ? ? 與select本質(zhì)上沒多大差別,管理描述符也是進行輪詢,根據(jù)描述符狀態(tài)進行處理,

????1.4優(yōu)點:

? ? ? ? ? 沒有最大文件描述符數(shù)量的限制

????1.5缺陷: ?

? ? ? ? ? ? 依然需要輪詢,性能開銷依然很大

3.epoll

????1.1函數(shù)原型:

? ? ? ? ? int epoll_create(int size);? ? ? ? ? ? ? ??

? ? ? ? ? int epoll_ctl( int epfd,int op, int fd,struct epoll_event *event);

? ? ? ? ? int epoll_wait( int epfd,struct epoll_event * events, int maxevents,int timeout);

? ? 1.2參數(shù)說明:

? ? ? ? ? ?epoll_create 創(chuàng)建一個句柄,內(nèi)部創(chuàng)建一個紅黑樹節(jié)點;epoll_ctl注冊要監(jiān)聽的事件類型,epfd是epoll_create 返回的句柄,op表示操作類型:EPOLL_CTL_ADD,EPOLL_CTL_MOD,EPOLL_CTL_DEL分別代表添加 修改 刪除,fd是要監(jiān)聽的描述符,event是要監(jiān)聽的事件;epoll_wait:等待事件的就緒。epfd 句柄,events 從內(nèi)核得到的就緒事件集合,maxevents告訴內(nèi)核events的大小,timeout表示等待的超時事件。

????????????成功返回就緒事件的數(shù)目,失敗返回-1,0表示超時。

????1.3運行機制:

? ? ? ? ? ?獲取事件的時候,無需遍歷整個被監(jiān)聽的描述符集,只要遍歷被內(nèi)核異步喚醒而加入Ready隊列的描述符集合就行了。

????1.4優(yōu)點:

? ? ? ? Linux下為了提高處理大批文件描述符而改進的poll,顯著提高了程序在大量并發(fā)連接中只有少量活躍的情況下CPU的利用率。

? ? ? epoll除了提供select/poll那種IO事件的水平觸發(fā)外,還提供了邊緣觸發(fā),使得用戶空間程序有可能緩存IO狀態(tài),減少epoll_wait調(diào)用,提高應(yīng)用程序效率。

? ? ? ? 水平觸發(fā):默認工作模式,epoll_wait檢測到描述符就緒并通知應(yīng)用程序時,應(yīng)用程序可以不立即處理該事件,下次調(diào)用epoll_wait時,會再次通知該事件。

? ? ? ? 邊緣觸發(fā):epoll_wait檢測到描述符就緒并通知應(yīng)用程序時,應(yīng)用程序必須立即處理,如果不處理,下次調(diào)用epoll_wait時不會再次通知此事件。

? ? ? ? 邊緣觸發(fā)大程度減少epoll事件的觸發(fā)次數(shù),效率比水平觸發(fā)模式下高。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容