select、poll以及epoll三组I/O复用函数的区别

三组I/O复用函数的区别
select、poll和epoll三组I/O复用系统调用。三者之间的异同
一、相同点:
1、这3组系统调用都能同时监听多个文件描述符
2、他们将等待有timeout参数指定的超时时间,直到一个或者多个文件描述符上有事件返回,返回值是就绪文件描述符的数量,返回0表示没有事件发生。
二、不同点:
1、事件集
  • 都通过某种结构体变量来告诉内核监听哪些文件描述符上的哪些事件。用该结构类型的参数获取内核处理的结果。
  1. select的参数类型没有 将文件描述符和事件绑定,仅仅是一个文件描述符的集合。
  2. poll的参数类型pollfd,将文件描述符和事件都定义在其中,任何事件都被统一处理,使编程接口简洁,并且内核修改每次都是pollfd结构体的revents成员,而events保持不变。因此下次应用程序调用poll时应用程序不需要重置pollfd的事件集参数。
  3. 小结:由于每次select和poll调用都返回整个用户注册事件的集合(就绪的+未就绪的)所以应用程序索引就绪文件描述符的时间复杂度是O(n);
  4. epoll在内核中维护一个事件表,并提供独立的系统调用epoll_ctl(),添加、删除、修改事件。故,每次epoll_wait调用events参数仅用来返回就绪事件,不需要反复从用户空间读入这些事件,所以应用程序索引就绪文件描述符的时间复杂度是O(1);
  • epoll_wait和poll分别用nfds和maxevents参数指定最多监听多少个文件描述符和事件,这两个数值都达到系统允许打开的最大文件描述符的数目(大小为65535),而select要监听最大文件描述符数量通常有限,虽然用户可以修改这个限制,但会导致不可预期的后果。
二、工作模式上的异同点:
1、select和poll只能在LT模式下;
2、epoll可以在工作高效的ET模式下。epoll支持EPOLLONESHOT事件,该事件可以进一步减少可读、可写和异常事件被触发的次数。
三、具体实现
1、实现原理:
  1. select和poll,采用轮询的方式。每次调用都要扫描整个注册文件描述符集合,并将就绪的文件描述符返回给用户程序,故检测就绪事件O(n);
  2. epoll_wait,采用回调函数的方法。内核检测到就绪文件描述符时将触发回调函数,回调函数将该文件描述符上对应的事件插入就绪事件队列,内核最后在适应的时机将该就绪事件队列中的内容拷贝到用户空间->epoll_wait无需轮询整个文件描述符的集合,来检测哪些事件已经就绪了。O(1)
2、适用情况:
  1. 当活动连接比较多的时候(回调函数被触发的过于频繁),epoll_wait的效率未必有select和poll高。
  2. epoll_wait适用于连接数量较多,但活动连接较少的情况

猜你喜欢

转载自blog.csdn.net/minld/article/details/76137322