带你深入了解IO多路复用技术

简介: IO多路复用技术是操作系统级的技术,也就是我们常说的底层原理。好多框架,中间件都是使用了IO多路复用技术,才使其具备更高的性能,比如我们经常使用的Redis、Nginx和我们耳熟能详的高性能通信框架Netty。本篇文章我们一起探究一下IO多路复用技术。

1 IO的理解

I - Input O - output

这里的IO我们常常指网络的IO,也就是指套接字Socket通信。网络传输的本质也就是输入输出,所有才有了IO之称。

Socket 的中文翻译为插口。双方要进行网络通信之前,各自需要创建一个 Socket,这相当于客户端和服务器都打开一个插口,双方读取和发送数据的时候,都通过这个插口建立数据通道,进行网络通信。

2 常见的IO模型

  • 同步阻塞IO(Blocking IO) 就是我们常说的BIO
  • 同步非阻塞IO(Non-blocking IO):默认创建的socket都是阻塞的,非阻塞IO要求socket被设置为NONBLOCK。注意这里所说的NIO并非Java的NIO(New IO)库。
  • IO多路复用(IO Multiplexing):即经典的Reactor设计模式,有时也称为异步阻塞IO,Java中的Selector和Linux中的epoll都是这种模型。这个就是我们Java常说的NIO,也是Netty的核心。
  • 信号驱动IO(signal driven IO)
  • 异步IO(Asynchronous IO):即经典的Proactor设计模式,也称为异步非阻塞IO。这就是我们Java常说的AIO。

同步: 前四种都属于同步IO,同步是指用户线程发起IO请求后,需要等待或者轮询内核IO操作完成后,才能继续执行。

异步: 异步是指用户线程发起IO请求后仍继续执行,当内核IO操作完成后会通知用户线程,或者调用用户线程注册的回调函数。

阻塞: 阻塞是指IO操作需要彻底完成后才返回到用户。

非阻塞: 非阻塞是指IO操作被调用后立即返回给用户一个状态值,无需等到IO操作彻底完成。

3 多路复用技术

多路复用技术是建立在内核提供的多路分离函数基础之上的,使用多路复用技术可以避免同步非阻塞IO模型中轮询等待等问题。

多路复用技术的最大优势是系统开销小,系统不必创建进程/线程,也不必维护这些进程/线程,从而大大减小了系统的开销。

谈及IO多路复用技术不得不介绍一下IO模型的发展:

最早期一个进程只能处理一个网络连接,后来演化成多进程,多线程处理,即每加入一个连接,操作系统就必须创建一个进程或者一个线程去处理IO,这样操作系统的压力无疑是巨大的。

IO多路复用技术就是为解决上述问题所产生的,使用IO多路复用技术可以使我们只需要一个进程就能处理多个网络连接。多个请求复用一个进程,这也是IO多路复用名称的由来。select, poll, epoll就是操作系统为我们提供的可以通过一个进程,获取多个事件的函数。

4 select, poll, epoll

select, poll, epoll 都是I/O多路复用的具体的实现

  • select 跨平台 1983年

    select 检测到的连接是有上限的,通常是1024,select 不是线程安全的。

  • poll (linux支持) 1997年

    poll修复了select的许多问题,去掉了连接上限,但是poll仍然不是线程安全的。

  • epoll (linux支持,效率更高)2002年

    epoll 可以说是I/O 多路复用最新的一个实现,epoll 修复了poll 和select绝大部分问题,并且epoll 是线程安全的,epoll 不仅告诉你sock组里面数据,还会告诉你具体哪个sock有数据。

select

select 实现多路复用的方式是,将已连接的 Socket 都放到一个文件描述符集合中,然后调用 select 函数将文件描述符集合拷贝到内核里,让内核来检查是否有网络事件产生,检查的方式很粗暴,就是通过遍历文件描述符集合的方式,当检查到有事件产生后,将此 Socket 标记为可读或可写, 接着再把整个文件描述符集合拷贝回用户态里,然后用户态还需要再通过遍历的方法找到可读或可写的 Socket,然后再对其处理。

对于 select 这种方式,需要进行 2 次「遍历」文件描述符集合,一次是在内核态里,一个次是在用户态里 ,而且还会发生 2 次「拷贝」文件描述符集合,先从用户空间传入内核空间,由内核修改后,再传出到用户空间中。

select 使用固定长度的 BitsMap,表示文件描述符集合,而且所支持的文件描述符的个数是有限制的,在 Linux 系统中,由内核中的 FD_SETSIZE 限制, 默认最大值为 1024,只能监听 0~1023 的文件描述符,这也就是select方式有检测连接上限最底层的原因。

poll

poll 不再使用 BitsMap 来存储所关注的文件描述符,它改用动态数组,以链表形式来组织,突破了 select 的文件描述符个数限制,当然还会受到系统文件描述符限制。

poll 和 select 并没有太大的本质区别,都是使用线性结构存储进程关注的 Socket 集合,因此都需要遍历文件描述符集合来找到可读或可写的 Socket,时间复杂度为 O(n),而且也需要在用户态与内核态之间拷贝文件描述符集合。这样的方式,在大规模请求下,性能会急剧下降。

epoll

epoll 是为解决 select/poll 带来的问题而产生的,也是目前最主流的。

首先,epoll 在内核里使用红黑树来跟踪进程所有待检测的文件描述字,把需要监控的 socket 通过 epoll_ctl() 函数加入内核中的红黑树里,通过对黑红树进行操作,这样就不需要像 select/poll 每次操作时都传入整个 socket 集合,只需要传入一个待检测的 socket,减少了内核和用户空间大量的数据拷贝和内存分配。

其次, epoll 使用事件驱动的机制,内核里维护了一个链表来记录就绪事件,当某个 socket 有事件发生时,通过回调函数会将其加入到这个就绪事件列表中,当用户调用 epoll_wait() 函数时,只会返回有事件发生的文件描述符的个数,不需要像 select/poll 那样轮询扫描整个 socket 集合,大大提高了检测的效率。

5 总结

仔细思考一下,为什么各个大厂会对数据结构与算法情有独钟呢?就如同IO多路复用这样的底层技术,在它的升级演进过程中数据结构都发挥了巨大的作用,高效的红黑树,能够直接将时间复杂度降低到 O(logn),还有就是一些设计思想的融入,如事件驱动等,可以极大的提高检测速度,就是这些让epoll的性能,大大的超过了select/poll。我们去学习这些技术,不光要去知道它的实现原理,更重要的是去思考它演进的过程,进而去推动技术的创新与发展。

目录
相关文章
|
1月前
|
网络协议 安全 Linux
Linux C/C++之IO多路复用(select)
这篇文章主要介绍了TCP的三次握手和四次挥手过程,TCP与UDP的区别,以及如何使用select函数实现IO多路复用,包括服务器监听多个客户端连接和简单聊天室场景的应用示例。
90 0
|
1月前
|
存储 Linux C语言
Linux C/C++之IO多路复用(aio)
这篇文章介绍了Linux中IO多路复用技术epoll和异步IO技术aio的区别、执行过程、编程模型以及具体的编程实现方式。
85 1
Linux C/C++之IO多路复用(aio)
|
27天前
|
人工智能 Cloud Native Java
云原生技术深度解析:从IO优化到AI处理
【10月更文挑战第24天】在当今数字化时代,云计算已经成为企业IT架构的核心。云原生作为云计算的最新演进形态,旨在通过一系列先进的技术和实践,帮助企业构建高效、弹性、可观测的应用系统。本文将从IO优化、key问题解决、多线程意义以及AI处理等多个维度,深入探讨云原生技术的内涵与外延,并结合Java和AI技术给出相应的示例。
91 1
|
1月前
|
Linux C++
Linux C/C++之IO多路复用(poll,epoll)
这篇文章详细介绍了Linux下C/C++编程中IO多路复用的两种机制:poll和epoll,包括它们的比较、编程模型、函数原型以及如何使用这些机制实现服务器端和客户端之间的多个连接。
24 0
Linux C/C++之IO多路复用(poll,epoll)
|
1月前
|
Java Linux
【网络】高并发场景处理:线程池和IO多路复用
【网络】高并发场景处理:线程池和IO多路复用
45 2
|
1月前
|
监控 网络协议 Java
IO 多路复用? 什么是 IO 多路复用? 简单示例(日常生活)来解释 IO 多路复用 一看就懂! 大白话,可爱式(傻瓜式)教学! 保你懂!
本文通过日常生活中的简单示例解释了IO多路复用的概念,即一个线程通过监控多个socket来处理多个客户端请求,提高了效率,同时介绍了Linux系统中的select、poll和epoll三种IO多路复用的API。
124 2
|
27天前
|
运维 Cloud Native 持续交付
云原生技术解析:从IO出发,以阿里云原生为例
【10月更文挑战第24天】随着互联网技术的不断发展,传统的单体应用架构逐渐暴露出扩展性差、迭代速度慢等问题。为了应对这些挑战,云原生技术应运而生。云原生是一种利用云计算的优势,以更灵活、可扩展和可靠的方式构建和部署应用程序的方法。它强调以容器、微服务、自动化和持续交付为核心,旨在提高开发效率、增强系统的灵活性和可维护性。阿里云作为国内领先的云服务商,在云原生领域有着深厚的积累和实践。
53 0
|
2月前
|
消息中间件 NoSQL Java
面试官:谈谈你对IO多路复用的理解?
面试官:谈谈你对IO多路复用的理解?
48 0
面试官:谈谈你对IO多路复用的理解?
|
2月前
|
网络协议 Java Linux
高并发编程必备知识IO多路复用技术select,poll讲解
高并发编程必备知识IO多路复用技术select,poll讲解
|
4月前
|
NoSQL
共识协议的技术变迁问题之WPaxos理常态下的IO请求处理如何解决
共识协议的技术变迁问题之WPaxos理常态下的IO请求处理如何解决
161 55