【计算机网络】高并发业务必备的Linux网络IO模型

简介: 【计算机网络】高并发业务必备的Linux网络IO模型

IO的操作也就是应用程序从TCP缓冲区中读取数据的时候。

网络I/O的本质是socket的读取,socket在linux中被抽象为流,I/O可以理解为对流的操作。对于一次I/O访问,数据会先被拷贝到操作系统的内核的缓冲区中,然后才会从操作系统内核的缓冲区拷贝到应用程序的地址空间。所以说当一个read操作发生时,他会经历两个阶段:

第一阶段:等待数据准备(Waiting for the data to be ready)
第二阶段:将数据从内核拷贝到进程中(Copy the data from the kernel to the process)

对于socket流而言:

第一步:通常涉及等待网络上的数据分组到达,然后被复制到内核的某个缓冲区
第二步:把数据从内核缓冲区复制到进程缓冲区

1.阻塞IO(BIO)

(1)什么是阻塞I/O

阻塞IO就是当应用程序向TCP缓冲区发起读取数据申请时,在内核数据没有准备好之前,应用程序会一致处于等待数据的状态,直到内核把数据准备好交给应用程序才结束。

术语描述:在应用程序调用recvfrom读取数据时,其系统调用直到数据包到达别并且被复制到应用缓冲区中或者发生错误时才返回,此期间一致处于等待,进程从调用直到返回这段时间被阻塞的成为阻塞IO。

(2)阻塞I/O流程


4cc8614744d84715839e9a09f0364513.jpg

  • 第一步:应用程序向内核发起recvfrom读取数据
  • 第二步:准备数据报(应用进程阻塞)
  • 第三步:将数据从内核复制到应用空间
  • 第四步:复制完成后,返回成功提示

2.非阻塞I/O(NIO)

(1)什么是非阻塞I/O

非阻塞I/O就是当应用程序发起读取数据时,如果内核没有准备好数据报,会返回给应用程序,不会让应用程序一致等待,但是应用程序要时不时去尝试调用,当数据包准备好时,将数据从内核复制到用户空间,这个过程也是同步的,阻塞的。

术语描述:非阻塞I/O是在应用调用recvfrom读取数据时,如果缓冲区中没有数据的话,就会直接返回一个EWOULDBLOCK错误,不会让应用一致等待。在没有数据时会即刻返回错误标识,那也意味着如果应用要读取数据就需要不断的调用recvfrom请求,直到读取到它要的数据为止。

(2)非阻塞I/O流程

d8fb5ca73b4a4e69ba488e970fe3f8f6.jpg

  • 第一步:应用进程向内核发起recvfrom读取数据
  • 第二步:没有数据报准备好,即刻返回EWOULDBLOCK错误码
  • 第三步:应用程序向内核再次发起recvfrom读取数据
  • 第四步:已有数据报就从内核拷贝到用户空间,否则还是返回错误码

3.I/O多路复用

(1)什么时I/O多路复用

I/O多路复用的思路就是系统提供了一种函数可以同时监控多个网络请求的操作,这个函数就是我们常说的select、poll、epoll函数,有了这个函数后,

应用线程通过调用select函数就可以同时监控多个网络请求,select函数监控的网络请求中只要有任何一个数据状态准备就绪了,select函数就会返回可读状态,这时询问线程再去通知处理数据的线程,对应线程此时再发起recvfrom请求去读取数据。

术语描述:进程通过将一个或者多个网络请求传递给select,阻塞在select操作之上,select帮我们侦测多个网络请求是否准备就绪,当有网络请求准备就绪时,select返回数据可读状态,应用程序在调用recvfrom读取数据。

(2)I/O多路复用流程

2d20c3bed7eb49d395237133164ade20.jpg

  • 第一步:进程发起网络请求到select函数调用进行阻塞
  • 第二步:select函数调用内核获取数据报
  • 第三步:select函数监控的网络请求中只要有任何一个数据状态准备就绪了,select函数就会返回可读状态
  • 第四步:询问线程再去通知处理数据的线程,对应线程在次发起recvfrom请求去读取数据

4.信号驱动I/O

(1)什么是信号驱动I/O

信号驱动I/O不是循环请求询问的方式去监控数据就绪状态,而是调用sigaction时候建立一个SIGIO的信号联系,当内核数据准备好之后在通过SISGIO信号通知线程数据准备好后的可读状态,当线程收到可读状态的信号后,此时在向内核发起recvfrom读取数据的请求,因为信号驱动I/O的模型下应用线程在发出信号监控后即可返回,不会阻塞,所以这样的方式下,一个应用线程也可以控制多个网络请求。


术语描述:首先开启套接字信号驱动I/O功能,并通过系统调用sigaction执行一个信号处理函数,此时请求即可返回,当数据准备就绪时,就生成对应进程的SIGIO信号,通过信号回调通知应用线程调用recvfrom来读取数据。

(2)信号驱动I/O流程


f442bc19f1544c12b1ee4bf1381f3ed0.jpg

  • 第一步:进程建立SIGIO的信号处理程序调用sigaction,然后返回
  • 第二步:内核准备好数据递交SIGIO给信号处理程序
  • 第三步:应用程序收到信号后,调用数据拷贝,复制完成返回数据报

5.异步I/O(AIO)

(1)什么是异步I/O

异步I/O应用只需要向内核发送一个read请求,告诉内核他要读取数据后即刻返回,内核收到请求后会建立一个信号联系,但数据准备就绪,内核会主动把数据从内核复制到用户空间,等所有操作都完成之后,内核会发起一个通知告诉应用,处理数据报完成。

术语描述:应用告知内核启动某个操作,并让内核在整个操作完成之后,通知应用,这种模型与信号驱动的主要区别在于信号驱动I/O是由内核通知我们何时开始下一个I/O,而异步I/O模型是由内核通知我们操作什么时候完成。

(2)异步I/O流程


dc410fc310c143af94da8aad54a05195.jpg

  • 第一步:异步I/O应用只需要向内核发送一个read请求,告诉内核他要读取数据后即刻返回
  • 第二步:内核收到请求后会建立一个信号联系,但数据准备就绪
  • 第三步:内核会主动把数据从内核复制到用户空间,等所有操作都完成之后,内核会发起一个通知告诉应用,处理数据报完成

6.IO多路复用的select-poll-epoll区别

select poll epoll
查找模式 遍历 遍历 回调
底层结构 bitmap 链表 红黑树
最大值 x86架构32位系统最大1024 x64架构64位系统最大2048 无限制 无限制,1G内存大概支持10万个句柄fd
IO效率 每次调用,线性遍历,时间复杂度O(n) 每次调用,线性遍历,时间复杂度O(n) 当fd就绪,系统注册的回调函数就会被调用,将就绪fd放到列表里,时间复杂度O(1)

image.png

相关文章
|
1月前
|
网络协议 前端开发 Java
网络协议与IO模型
网络协议与IO模型
网络协议与IO模型
|
15天前
|
网络协议 算法 网络性能优化
计算机网络常见面试题(一):TCP/IP五层模型、TCP三次握手、四次挥手,TCP传输可靠性保障、ARQ协议
计算机网络常见面试题(一):TCP/IP五层模型、应用层常见的协议、TCP与UDP的区别,TCP三次握手、四次挥手,TCP传输可靠性保障、ARQ协议、ARP协议
|
16天前
|
网络协议 物联网 API
Python网络编程:Twisted框架的异步IO处理与实战
【10月更文挑战第26天】Python 是一门功能强大且易于学习的编程语言,Twisted 框架以其事件驱动和异步IO处理能力,在网络编程领域独树一帜。本文深入探讨 Twisted 的异步IO机制,并通过实战示例展示其强大功能。示例包括创建简单HTTP服务器,展示如何高效处理大量并发连接。
38 1
|
17天前
|
存储 关系型数据库 MySQL
查询服务器CPU、内存、磁盘、网络IO、队列、数据库占用空间等等信息
查询服务器CPU、内存、磁盘、网络IO、队列、数据库占用空间等等信息
191 2
|
1月前
|
开发者
什么是面向网络的IO模型?
【10月更文挑战第6天】什么是面向网络的IO模型?
20 3
|
1月前
|
数据挖掘 开发者
网络IO模型
【10月更文挑战第6天】网络IO模型
38 3
|
1月前
|
缓存 Java Linux
硬核图解网络IO模型!
硬核图解网络IO模型!
|
1月前
|
数据挖掘 开发者
网络IO模型如何选择?
网络IO模型如何选择?【10月更文挑战第5天】
19 2
|
15天前
|
网络协议 调度 开发者
Python网络编程:Twisted框架的异步IO处理与实战
【10月更文挑战第27天】本文介绍了Python网络编程中的Twisted框架,重点讲解了其异步IO处理机制。通过反应器模式,Twisted能够在单线程中高效处理多个网络连接。文章提供了两个实战示例:一个简单的Echo服务器和一个HTTP服务器,展示了Twisted的强大功能和灵活性。
28 0
|
30天前
|
存储 分布式计算 负载均衡