1、引言

在之前的博文中,我们陆续的介绍了I/O复用的三种技术——select、poll和epoll。
调用这三组系统调用能够同时监听多个文件描述符。直到一个或者多个文件描述符上有事件发生时返回,返回值就是就绪的文件描述符的数量。
现在,我们主要从事件集合的记录方式、最大支持文件描述符数、工作模式和具体实现几个方面进一步比较他们的异同。

2、比较

1、事件集合
这三种方式都是通过某种结构体变量来告诉内核监听哪些文件描述符及其事件。具体的区别如下:

  • select的参数类型是fd_set的文件描述符集合。因为其没有将文件描述符和事件绑定的缘故,他需要提供三个这种类型的参数来分别传入和输入可读、可写以及异常等事件。注意!!由于内核对fd_set集合的在线修改,应用程序下次调用select前不得不重置这3个fd_Set集合
  • poll的参数类型pollfd就是把文件描述符和事件都定义在其中了。任何事件都是可以被统一处理的。因为内核events成员保持不变,因此下次调用poll时应用程序不需要重置pollfd类型的事件参数
  • epoll则是自己在内核中维护了一个事件表,并且提供了一个独立的系统调用epoll_ctl来控制往其中添加、删除、修改事件。这样的好处就是,无须反复从用户空间读入这些事件,epoll_wait系统调用都直接从内核事件表中取得用户注册的事件。

2、最大支持的文件描述符

  • poll和epoll_wait可以有自己的参数来指定最多监听多少个文件描述符和事件。但是最多不能超过系统允许打开的最大文件描述符的个数65535个
  • select允许监听的最大文件描述符的数量通常有限制为1024

3、工作模式

  • select和poll只能工作在相对低效的LT(电平触发)模式
  • epoll可以工作在ET(边沿触发)高效模式。并且epoll更进一步还可以支持EPOLLNESHOT事件。这种事件能进一步减少可读、可写和异常等事件被触发的次数

4、返回值

  • select和poll最后都会把用户注册的所有事件都返回,因此用户程序在检测其就绪的复杂度就为O(n)
  • epoll_wait系统调用的events参数仅用来返回就绪的事件,这使得应用程序索引就绪文件描述符的时间复杂度达到了O(1)

5、具体实现

  • select和poll采用的都是轮询的方式,即每次调用都要扫描整个注册文件描述符集合,并将就绪的文件描述符返回给用户程序。
  • epoll_wait就是采用回调的方式。即内核一旦检测到有就绪的文件描述符的时候将触发回调函数,回调函数就是将该文件描述符上对应的事件插入到内核就绪事件队列中(从红黑树上取下放到双向就绪链表中)。内核最后在适当的时机将就绪事件队列中的内容拷贝到用户空间。

总结一下:回调函数的功能就是把就绪的文件描述符和事件添加到rdlist里面去。调用epoll_wait的时候只需要看这个rdlist是否为空。不为空就表示有就绪事件发生

6、最终总结
【Linux】——I/O复用三种方式总结

相关文章:

  • 2021-07-20
  • 2022-02-03
  • 2021-12-26
  • 2021-10-31
  • 2021-08-04
  • 2022-02-08
  • 2021-07-01
猜你喜欢
  • 2021-10-15
  • 2021-09-05
  • 2021-07-31
  • 2021-10-10
  • 2021-09-12
  • 2021-11-07
相关资源
相似解决方案