select
int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout);
1)用户通过三个参数传入感兴趣的读、写、异常事件,在select调用后,事件集合会被修改,所以每次调用select,都必须重置这三个集合
2)有最大连接上限,一般是默认1024,要通过编译内核的方式才能实现修改
3)只能工作在LT(水平触发模式)
4)要通过轮询的方式检查就绪的文件描述符
poll
int poll(struct pollfd *fds, nfds_t nfds, int timeout);//fds 是一个结构体数组
struct pollfd {
int fd; /* file descriptor */
short events; /* requested events */
short revents; /* returned events */
};
1)用户通过fds[i].events传入感兴趣事件,内核通过修改fds[i].revents反馈就绪的事件
2)最大上限可为65535,在配置文件(/etc/security/limits.conf)修改上限
3)只能工作在LT(水平触发模式)
4)要通过轮询方式检查就绪的文件描述符
epoll
int epoll_create(int size);
int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event); //event 是结构体指针
op:
EPOLL_CTL_ADD //添加
EPOLL_CTL_MOD //修改
EPOLL_CTL_DEL //删除
int epoll_wait(int epfd, struct epoll_event *events,int maxevents, int timeout); //events是结构体数组首地址
typedef union epoll_data {
void *ptr;
int fd;
uint32_t u32;
uint64_t u64;
} epoll_data_t;
struct epoll_event {
uint32_t events; /* Epoll events */
epoll_data_t data; /* User data variable */
};
1)将感兴趣事件添加到红黑树,无需每次都传入用户感兴趣事件,就绪事件会写入events结构体数组中
2)支持最大监听上限为65535
3)支持ET/LT工作模式
4)满足条件的事件直接传出到event ,无须轮询
总结:epoll适用于连接数量较多,但活动连接较少的情况