IO多路复用:select/poll/epoll
select
int select (int maxfds,fd_set * readfds,fd_set * writefds,fd_set * errorfds,struct timeval* timeout)
返回值:有變化的描述符,返回值大于零,且為描述符個數;等于零,超時或者沒有變化的描述符;-1出錯。
timeout參數
1)null時,select將會一直阻塞,直到有監聽的描述符集合里面描述符發生了變化;
2)0時,select 會立即返回,有無描述符發生變化都會立即返回;
3)大于零的值,指定超時時間,超出時間就返回;
?
Poll
int poll (struct pollfd* fds , unsigned int nfds , int timeout)
struct pollfd{
? ? int fd;
? ? short events;
? ? short revents;
}
返回值:大于零,返回revents中不為0的文件描述符個數;等于零,超時或者沒有描述符就緒;-1,調用出錯。
timeout參數:
?
1)負數,無限超時;一直等待,直到一個指定的事件發生;? ?相當于selsect中的NULL;
2)0;表示立即返回;無論是否有已經準備好的描述符;
3)大于零,指定等待的超時時間;超時后返回
?
?
epoll
創建epoll句柄
int epoll_create (int size);
向內核注冊,修改或者刪除 一個描述符
int epoll_ctl (int epfd, int operator , int fd , struct epoll_events * event?);
等待事件的產生
int epoll_wait (int epfd, struct epoll_events*events , int maxevents , int timeout);
timeout參數:0立即返回,-1將永久阻塞直到有一個描述符有事件產生;大于零,指定超時時間
?
select、poll、epoll的區別
1)select : 描述符集合有上限,一般是1024/2048;每次需要線性遍歷描述符集合獲得描述符的事件狀態,對于分布的比較稀疏的比較少的描述符,效率會很低;每次fd_set在select返回之后都會發生變化;需要重新初始化;但移植性比較好,在某些unix系統上不支持poll,超時時間精度比較高!
2)poll相對于select而言,描述符數量遠遠大于select,是喲個特定大小的數組來保存監控的描述符,從而不受描述符值大小的影響;poll將監控的輸入事件和輸出事件分開,允許在每次返回后,被監控的文件數組可以被復用而不需要重新初始化;
3)epoll 使用一個文件描述符管理多個描述符。支持一個進程打開大數目的描述符,也即是描述符數量不受限制,對于支持上萬連接的IM服務器而言,較為實用!上限是最大可以打開的文件數目;IO效率不隨描述符的數量的增加而減少。在每個注冊到內核的fd上實現了回調函數,只有當當前socket活躍的時候才會去調用回調函數,所以epoll只會對活躍的socket進行操作(即事件驅動)。而select/poll要線性掃描所有的集合,導致效率下降。epoll將用戶關系的文件描述符的事件存放到內核的事件表中,避免了用戶空間和內核空間數據的多次拷貝
總結
以上是生活随笔為你收集整理的IO多路复用:select/poll/epoll的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 网络:窗口控制下的重发机制、流量控制
- 下一篇: Java集合:set的遍历方式