一文搞懂常见的网络I/O模型

简介: 一文搞懂常见的网络I/O模型

对于网络I/O模型的学习,在操作系统中是非常重要的一环,因为I/O也同样是我们系统设计中至关重要的一个方面和要考虑的因素,因此想利用一篇文章来解析一下,就目前而言,业界对五种网络I/O模型的分类,主要分为以下

  • 阻塞IO模型
  • 非阻塞IO模型
  • 多路复用IO模型
  • 信号驱动IO模型
  • 异步IO模型

根据自身学习和一些资料的参考,作出如下图示内容

1 概念简述

根据图示的这些分类,我们可以对比一下概念

(1)同步和异步的概念描述的是用户线程与内核的交互方式:

  • 同步是指用户线程发起IO请求后需要等待或者轮询内核IO操作完成后才能继续执行;
  • 异步是指用户线程发起IO请求后仍继续执行,当内核IO操作完成后会通知用户线程,或者调用用户线程注册的回调函数。

(2)阻塞和非阻塞的概念描述的是用户线程调用内核IO操作的方式:

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

(3)多路复用I/O

  • I/O多路复用就通过一种机制,可以监视多个描述符,一旦某个描述符就绪(一般是读就绪或者写就绪),能够通知程序进行相应的读写操作。

(4)事件驱动I/O

  • 事件驱动I/O本质上就是将I/O操作转化为程序需要处理的事件,减少了等待机制,而是利用事件触发的机制,增加了效率。

2 socket-同步阻塞I/O

socket 是进程间通信里是可以跨主机间通信。对于Socket的编程过程我们也比较熟悉:

(1)服务端调用 socket() 函数

(2)然后服务端调用 bind() 函数,给 Socket 绑定一个 IP 地址和端口

(3)绑定完 IP 地址和端口后,调用 listen() 函数监听

(4)服务端进入了监听状态后,通过调用 accept() 函数,来从内核获取客户端的连接,如果没有客户端连接,则会阻塞等待客户端连接的到来

(5)客户端在创建好 Socket 后,调用 connect() 函数发起连接,该函数的参数要指明服务端的 IP 地址和端口号

(6)然后 TCP 三次握手

(7)连接建立后,客户端和服务端就开始相互传输数据了,双方都可以通过 read() 和 write() 函数来读写数据

(图片来自:https://blog.csdn.net/qq_34827674/article/details/115619261)

多进程模型

(图片来自:https://blog.csdn.net/qq_34827674/article/details/115619261)

多线程引入

(图片来自:https://blog.csdn.net/qq_34827674/article/details/115619261)

综上,以上的Socket不管是单进程模式,还是多进程或多线程模式,他们的原理都是阻塞的,也就是下一个客户端进程的处理都需要等待当然客户端请求被处理完成,同理,服务端也会一直处于监听的状态,直到接受请求时才会去处理。

3 select-同步阻塞&多路复用I/O

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

select 使用固定长度的 BitsMap,表示文件描述符集合,而且所支持的文件描述符的个数是有限制的,默认最大值为 1024,只能监听 0~1023 的文件描述符。

(图片来自:https://www.cnblogs.com/yanguhung/p/10145755.html

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

4 poll-同步阻塞&加强版多路复用I/O

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

但是 poll 和 select 并没有太大的本质区别,都是使用线性结构存储进程关注的 Socket 集合,因此都需要遍历文件描述符集合来找到可读或可写的 Socket,时间复杂度为 O(n),而且也需要在用户态与内核态之间拷贝文件描述符集合,这种方式随着并发数上来,性能的损耗会呈指数级增长。

5 epoll-同步阻塞&加强版多路复用&事件驱动I/O

epoll 相比 select/poll增强了这两个方面:

  • 第一点,epoll 在内核里使用红黑树来跟踪进程所有待检测的文件描述字,把需要监控的 socket 通过 epoll_ctl() 函数加入内核中的红黑树里,红黑树是个高效的数据结构,增删查一般时间复杂度是 O(logn),通过对这棵黑红树进行操作,这样就不需要像 select/poll 每次操作时都传入整个 socket 集合,只需要传入一个待检测的 socket,减少了内核和用户空间大量的数据拷贝和内存分配。
  • 第二点, epoll 使用事件驱动的机制,内核里维护了一个链表来记录就绪事件,当某个 socket 有事件发生时,通过回调函数内核会将其加入到这个就绪事件列表中,当用户调用 epoll_wait() 函数时,只会返回有事件发生的文件描述符的个数,不需要像 select/poll 那样轮询扫描整个 socket 集合,大大提高了检测的效率。

    (图片来自:https://blog.csdn.net/qq_34827674/article/details/115619261)

epoll 的方式即使监听的 Socket 数量越多的时候,效率不会大幅度降低,能够同时监听的 Socket 的数目也非常的多了,上限就为系统定义的进程打开的最大文件描述符个数。因而,epoll 被称为解决 C10K 问题的利器。

Tips:

epoll 是解决 C10K 问题的利器,通过两个方面解决了 select/poll 的问题:

(1)epoll 在内核里使用「红黑树」来关注进程所有待检测的 Socket,红黑树是个高效的数据结构,增删查一般时间复杂度是 O(logn),通过对这棵黑红树的管理,不需要像 select/poll 在每次操作时都传入整个 Socket 集合,减少了内核和用户空间大量的数据拷贝和内存分配。

(2)epoll 使用事件驱动的机制,内核里维护了一个「链表」来记录就绪事件,只将有事件发生的 Socket 集合传递给应用程序,不需要像 select/poll 那样轮询扫描整个集合(包含有和无事件的 Socket ),大大提高了检测的效率。

6 异步I/O

异步I/O目前仅有概念的存在。

异步IO的概念和同步IO相对。当一个异步过程调用发出后,调用者不能立刻得到结果。实际处理这个调用的部件在完成后,通过状态、通知和回调来通知调用者。在一个CPU密集型的应用中,有一些需要处理的数据可能放在磁盘上。预先知道这些数 据的位置,所以预先发起异步IO读请求。等到真正需要用到这些数据的时候,再等待异步IO完成。使用了异步IO,在发起IO请求到实际使用数据这段时间内,程序还可以继续做其他事情

7 总结

通过对网络I/O模型的学习,从阻塞到非阻塞,从同步到异步再到事件驱动,可以说效率是大大提高的,并且从网络延伸到放放面面,比如Spring框架的Reactor机制,Kafka消息队列等等。

今天的文章就到这里,bye~

参考文章:

https://www.cnblogs.com/yanguhung/p/10145755.html

https://blog.csdn.net/qq_34827674/article/details/115619261

https://baike.baidu.com/item/%E5%BC%82%E6%AD%A5IO/6018433?fr=aladdin

相关文章
|
4天前
|
监控 安全 BI
什么是零信任模型?如何实施以保证网络安全?
随着数字化转型,网络边界不断变化,组织需采用新的安全方法。零信任基于“永不信任,永远验证”原则,强调无论内外部,任何用户、设备或网络都不可信任。该模型包括微分段、多因素身份验证、单点登录、最小特权原则、持续监控和审核用户活动、监控设备等核心准则,以实现强大的网络安全态势。
|
2月前
|
机器学习/深度学习 算法 数据安全/隐私保护
基于BP神经网络的苦瓜生长含水量预测模型matlab仿真
本项目展示了基于BP神经网络的苦瓜生长含水量预测模型,通过温度(T)、风速(v)、模型厚度(h)等输入特征,预测苦瓜的含水量。采用Matlab2022a开发,核心代码附带中文注释及操作视频。模型利用BP神经网络的非线性映射能力,对试验数据进行训练,实现对未知样本含水量变化规律的预测,为干燥过程的理论研究提供支持。
|
21天前
|
存储 缓存 监控
Docker容器性能调优的关键技巧,涵盖CPU、内存、网络及磁盘I/O的优化策略,结合实战案例,旨在帮助读者有效提升Docker容器的性能与稳定性。
本文介绍了Docker容器性能调优的关键技巧,涵盖CPU、内存、网络及磁盘I/O的优化策略,结合实战案例,旨在帮助读者有效提升Docker容器的性能与稳定性。
54 7
|
1月前
|
存储 网络协议 安全
30 道初级网络工程师面试题,涵盖 OSI 模型、TCP/IP 协议栈、IP 地址、子网掩码、VLAN、STP、DHCP、DNS、防火墙、NAT、VPN 等基础知识和技术,帮助小白们充分准备面试,顺利踏入职场
本文精选了 30 道初级网络工程师面试题,涵盖 OSI 模型、TCP/IP 协议栈、IP 地址、子网掩码、VLAN、STP、DHCP、DNS、防火墙、NAT、VPN 等基础知识和技术,帮助小白们充分准备面试,顺利踏入职场。
83 2
|
1月前
|
运维 网络协议 算法
7 层 OSI 参考模型:详解网络通信的层次结构
7 层 OSI 参考模型:详解网络通信的层次结构
121 1
|
2月前
|
网络协议 前端开发 Java
网络协议与IO模型
网络协议与IO模型
116 4
网络协议与IO模型
|
2月前
|
机器学习/深度学习 网络架构 计算机视觉
目标检测笔记(一):不同模型的网络架构介绍和代码
这篇文章介绍了ShuffleNetV2网络架构及其代码实现,包括模型结构、代码细节和不同版本的模型。ShuffleNetV2是一个高效的卷积神经网络,适用于深度学习中的目标检测任务。
100 1
目标检测笔记(一):不同模型的网络架构介绍和代码
|
1月前
|
网络协议 算法 网络性能优化
计算机网络常见面试题(一):TCP/IP五层模型、TCP三次握手、四次挥手,TCP传输可靠性保障、ARQ协议
计算机网络常见面试题(一):TCP/IP五层模型、应用层常见的协议、TCP与UDP的区别,TCP三次握手、四次挥手,TCP传输可靠性保障、ARQ协议、ARP协议
|
1月前
|
机器学习/深度学习 人工智能 算法
【车辆车型识别】Python+卷积神经网络算法+深度学习+人工智能+TensorFlow+算法模型
车辆车型识别,使用Python作为主要编程语言,通过收集多种车辆车型图像数据集,然后基于TensorFlow搭建卷积网络算法模型,并对数据集进行训练,最后得到一个识别精度较高的模型文件。再基于Django搭建web网页端操作界面,实现用户上传一张车辆图片识别其类型。
85 0
【车辆车型识别】Python+卷积神经网络算法+深度学习+人工智能+TensorFlow+算法模型
|
2月前
|
机器学习/深度学习 编解码 算法
【深度学习】经典的深度学习模型-01 开山之作:CNN卷积神经网络LeNet-5
【深度学习】经典的深度学习模型-01 开山之作:CNN卷积神经网络LeNet-5
50 0
下一篇
DataWorks