IT袋

当前位置:主页 > 经验教程 > 系统教程 >

Linux

Linux I/O模型详解(5)

时间:2024-01-14 17:25:08 来源:IT袋 作者:马勇
导读:Linux,我们看下 poll 的函数定义: int poll(struct pollfd *fds, nfds_t nfds, int timeout) fds: 是一个指向 pollfd 结构数组的指针; **nfds: **是数组中的文件描述符数量; **timeout:

Linux

我们看下 poll 的函数定义:

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

  • fds:是一个指向 pollfd 结构数组的指针;
  • **nfds: **是数组中的文件描述符数量;
  • **timeout: ** 是超时时间(以毫秒为单位)
    • timeout = -1:poll 将一直阻塞直到有文件描述符准备好;
    • timeout = 0:poll 立即返回,不等待;
    • timeout > 0:poll 将等待指定的时间。
  • 返回值:是就绪文件描述符的数量,或者在超时或出错时返回 0。

epoll

epoll 是 Linux 操作系统中的一种高效 I/O 多路复用机制,用于监视多个文件描述符的状态,以便进行非阻塞I/O操作。

它是对 select 和 poll 的改进,提供了更好的性能和扩展性,特别适用于处理大规模并发连接, 如 Web 服务器、聊天服务器和网络游戏服务器等,因为它具有出色的性能和扩展性。

它主要在 Linux 操作系统上可用,而不是跨平台的,因此不适用于需要跨平台支持的应用程序。

在 Linux 2.4 内核前主要是 select 和 poll,自 Linux 2.6 内核正式引入 epoll 以来,epoll 已经成为了目前实现高性能网络服务器的必备技术。

epoll 使用了3个方法来实现 select 方法要做的事:

  • epoll_create():新建 epoll 描述符
  • **epoll_ctrl() : **添加或者删除所有待监控的连接
  • **epoll_wait(): **返回的活跃连接

与 select 相比,epoll 分清了频繁调用和不频繁调用的操作。

例如,epoll_ctrl 是不太频繁调用的,而 epoll_wait 是非常频繁调用的。

这时,epoll_wait 却几乎没有入参,这比 select 的效率高出一大截。

而且它也不会随着并发连接的增加使得入参越发多起来,导致内核执行效率下降。

除此之外, epoll 还增加了很多机制, 用来提升性能:

  • mmap(共享内存):epoll 是通过内核与用户空间 mmap 同一块内存实现的。mmap 将用户空间的一块地址和内核空间的一块地址同时映射到相同的一块物理内存地址(不管是用户空间还是内核空间都是虚拟地址,最终要通过地址映射映射到物理地址),使得这块物理内存对内核和对用户均可见,减少用户态和内核态之间的数据交换。内核可以直接看到 epoll 监听的句柄,效率高。
  • 红黑树:红黑树将存储 epoll 所监听的套接字。上面 mmap 出来的内存如何保存 epoll 所监听的套接字,必然也得有一套数据结构,epoll 在实现上采用红黑树去存储所有套接字,当添加或者删除一个套接字时(epoll_ctl),都在红黑树上去处理,红黑树本身插入和删除性能比较好,时间复杂度 O(logN)。
  • 链表:

相关阅读