select/poll/epoll的区别

select:在一段时间内,监听用户感兴趣的文件描述符上的可读、可写和异常事件。

poll:和select类似,也是在一段时间内轮询一定数量的文件描述符,监听是否有就绪的文件描述符。

epoll:使用一组函数来完成任务,epoll把关心的文件描述符的事件放入内核事件表中,每次只用监听内核事件表中的就绪事件即可。

1、三者函数原型不同

int select( int nfds  ,struct fd_set* readfds  ,fd_set* writefds  ,fd_set* exceptfds,   struct timeval* timeout)

参数:

nfds:被监听的文件描述符的总数。

readfds /writefds / exceptfds:分别指向可读、可写和异常事件对应的文件描述符集合。应用程序调用select函数时,通过这三个参数传入自习感兴趣的文件描述符,select调用返回时,内核修改它们来通知应用程序哪些文件描述符已经就绪。

timeout:设置超时时间

 

int poll(struct pollfd* fds  ,nfds_t  nfds,int timeout)

fds:是pollfd类型的数组,它指定文件描述符上发生的事件。Pollfd结构体定义如下:

struct pollfd{

int  fd;文件描述符

short  events;注册事件

short  revents;实际发生的事件,由内核填写

}

nfds:指定监听事件集合fds的大小

timeout:指定超时时间

 

epoll的三个函数

int  epoll_create(int size),创建一个额外的内核事件表,size是事件表的大小。

int  epoll_ctl(int epfd ,int  op, int fd,epoll_event* event),根据op参数的操作类型,对事件表进行操作。

int  epoll_wait(int  epfd,epoll_event *events ,int maxevents ,int  timeout),从就绪链表中取就绪事件的描述符和事件

 

2、使用方面的区别

select函数通过3个fd_set结构体变量分别为内核传递用户关注的可读、可写和异常事件。故select不能处理更多的事件类型,并且内核也通过这三个结构体变量返回就绪的文件描述符,所以每次使用之前,都要重新设置这3个结构体变量。

poll函数将用户关注的文件描述符以及其关注的事件、内核返回的文件描述符发生的事件分离表示,并且通过一个用户数组将所有的文件描述符传递给内核,因此,poll能关注的事件类型更多,每次调用不需要重新设置。

epoll是通过一组函数来完成,通过epoll_create创建一个内核事件表,通过epoll——ctl函数添加、删除和修改事件。Epoll_wait只需要从内核事件表中读取用户的注册事件即可。

 

3、使用限制

select关注的文件描述符最多1024个,poll和epoll都能达到65535个

 

4、使用效率

 select、poll每次调用都需要将用户空间的文件描述符拷贝到内核空间,epoll则只需要拷贝一次,效率更高。

select、poll每次都要将所有的文件描述符返回,所以应用程序检索就绪文件描述符为O(n)。Epoll通过通过events参数返回所有就绪的文件描述符,应用程序检索就绪的文件描述符的时间复杂度是O(1)。

select、poll只能工作在LT模式下,而epoll可以在ET模式下工作,更高效。

 

 

 

猜你喜欢

转载自blog.csdn.net/ShWe_yayaya/article/details/82388363