Linux-I/O多路複用(select,poll,epoll)
文章目錄
- Linux-I/O多路複用(select,poll,epoll)
-
- select
-
- 函數原型
- 缺點
- poll
-
- 函數原型
- 對select改進
- epoll
-
- 函數原型
- 改進
- 觸發模式
- 應用
select
函數原型
select系統調用會阻塞程序,當有資料到來系統将fd_set對應位置位,select函數傳回.select會将fd_set拷貝到核心.其實select隻能傳回一個準備好的檔案描述符,如果在主線程對相應的檔案描述符做操就會阻塞,使得其他準備好的檔案描述符得不到處理,是以就有了Reactor模型.
#include <sys/select.h>
int select(int nfds, fd_set *rdfds, fd_set *wtfds,
fd_set *exfds, struct timeval *timeout)
缺點
- fd_set組成的bitmap隻有1024個
- fd_set不可重用,每次都要重新設定fd_set
- 拷貝fd_set有開銷
- 需要周遊fd_set
poll
函數原型
poll使用了pollfd結構體,有資料到來系統将polfd.revents置位
對select改進
- 使用pollfd數組,可以管理大于1024個檔案描述符
- pollfd可重用
- 周遊範圍變小(pollfd數組),poll傳回準備好的檔案描述符個數
epoll
函數原型
有資料到來系統将epfd用重排來置位(将有資料的epfd放在數組前面)
//建立size個監聽,傳回一個紅黑樹的檔案描述符epfd
int epoll_create(int size)
//epfd控制
int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event)
//等待epfd準備好
int epoll_wait(int epfd, struct epoll_event *events, int maxevents, int timeout)
使用以下指令檢視可以使用的pollfd數量
cat /proc/sys/fs//file-max
改進
- epfd使用者态與核心态共用
- 周遊範圍變小(準備好的epfd數組),epoll_wait傳回準備好的檔案描述符個數
觸發模式
- 邊沿觸發(ET):檔案描述符從無資料狀态到有資料狀态epoll才觸發
- 水準觸發(LT):檔案描述符有資料epoll就觸發
應用
- redis
- nginx
- java NIO(Linux系統)