Linux IO多路复用之select,epoll实现分析
一.select的实现在fs/select.c:
1.我们来看fd_set的定义:
可见fd_set最多能容纳1024个fd;当然也可以修改__FD_SETSIZE宏并编译内核来增大fd_set管理的fd数,但是这样会导致性能下降,具体原因见第3点。
2.select的三个fd_set的参数inp,oup,exp会进行两次用户空间和内核空间之间的拷贝:
第一次作为入参拷贝到内核空间,第二次将fd的就绪状态作为出参拷贝到用户空间。
3.我们来看select函数的主体do_select:
通过遍历fd_set中的每个fd并调用 fp_op->poll来检查fd的就绪状态,时间复杂度为 O(n)。
二.
epoll的操作需要三个接口:
#include <sys/epoll.h>long epoll_create(int size);
long epoll_ctl(int epfd, int op, int fd, struct epoll_event *event);
long epoll_wait(int epfd, struct epoll_event *events, int maxevents, int timeout);
epoll的实现在fs/eventpoll.c
1.long epoll_create(int size)
创建一个epoll的fd,size表示fd的最多个数,从实现来看,对fd的个数没有限制。在使用完epoll后,需要调用close()关闭。
2.long epoll_ctl(int epfd, int op, int fd, struct epoll_event *event)
添加,删除监听的fd
3.long epoll_wait(int epfd, struct epoll_event *events, int maxevents, int timeout)
当fd就绪时,会添加到rdllist( 在ep_poll_callback()函数里):
epoll_wait对rdllist里的每个fd执行f_op->poll(),也就是说只会poll处于就绪态的fd,因此比select效率高:
reference:
https://blog.****.net/apacat/article/details/51375950