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ā)模式下高。