Linux网络-五种IO模型

Linux系统
311
0
0
2023-01-13

Linux网络-高级IO

  • 零、前言
  • 一、什么是IO
  • 二、五种IO模型
  • 1、阻塞IO
  • 2、非阻塞IO
  • 3、信号驱动IO
  • 4、IO多路转接
  • 5、异步IO
  • 三、高级IO重要概念
  • 1、同步通信 vs 异步通信
  • 2、阻塞 vs 非阻塞
  • 3、其他高级IO

零、前言

本章主要就Linux网络讲解非常重要的一个话题-高级IO

一、什么是IO

IO是输入input输出output的首字母缩写形式,直观意思是计算机输入输出,它描述的是计算机的数据流动的过程,因此IO第一大特征是有数据的流动
  • 从直观层面去理解IO:
IO是计算机和外设之间的数据流动过程,外设包含两种重要设备(但不限于此):输入设备和输出设备。像鼠标键盘属于输入设备,将人的指令转成“鼠键行为”这种数据传给主机;显示器是输出设备,主机通过运算,把“返回信息”这种数据传给显示器
  • 从计算机架构的角度去理解IO:
从计算机架构上来讲,任何涉及到计算机核心(CPU和内存)与其他设备间的数据转移的过程就是IO。本体就是计算机核心(CPU和内存)。例如从硬盘上读取数据到内存,是一次输入,将内存中的数据写入到硬盘就产生了输出
  • 从编程的角度去理解IO:
IO的主体是其应用程序的运行态,即进程,特别强调的是我们的应用程序其实并不存在实质的IO过程,真正的IO过程是操作系统的事情,这里把应用程序的IO操作分为两种动作:IO调用和IO执行,IO调用什么是应用程序对操作系统IO功能的一次触发,IO执行是操作系统的工作 IO调用的目的是将进程的内部数据迁移到外部即输出,或将外部数据迁移到进程内部即输入。这里,外部数据指非进程空间数据,在编程时,通常讨论的场景是来自外部存储设备的数据,如硬盘、CD-ROM、以及需要socket通信传输的网络数据
  • 以一个进程的输入类型的IO调用为例,它将完成或引起如下工作内容:
  1. 进程向操作系统请求外部数据
  2. 操作系统将外部数据加载到内核缓冲区
  3. 操作系统将数据从内核缓冲区拷贝到进程缓冲区
  4. 进程读取数据继续后面的工作

二、五种IO模型

1、阻塞IO

  • 概念及介绍:
  1. 在进行IO读写时,系统调用会一直进行等待(不做其他的),直到内核将数据准备好,得到数据后才调用返回
  2. 阻塞IO是最常见的IO模型,所有的套接字函数调用默认都是阻塞方式
  • 举例:
钓鱼时,一个人一条杆子,一动不动看着浮漂的动静,看是否有鱼上钩
  • 示图:

img

2、非阻塞IO

  • 概念及介绍:
  1. 如果内核还未将数据准备好,系统调用仍然会直接返回,并且返回EWOULDBLOCK错误码
  2. 非阻塞IO往往需要程序员循环的方式反复尝试读写文件描述符(查看数据是否准备好了),这个过程称为轮询,这对CPU来说是较大的浪费,一般只有特定场景下才使用
  3. 调用返回错误码时,说明此时数据没有准备好,那么就可以选择做一些其他的事情(非阻塞),过一段时间后再次进行访问查看数据是否准备好(轮询)
  • 举例:
钓鱼时,一个人一条杆子,一会看着浮漂,没动静时就刷一会手机,隔段时间再看浮漂的动静
  • 示图:

img

3、信号驱动IO

  • 概念及介绍:
  1. 信号驱动IO模型并不主动去内核是否将数据准备好,这是并不高效的IO方式
  2. 它赋予关注的事件一套处理机制,在内核将数据准备好的时候,内核主动使用SIGIO信号通知应用程序进行IO操作
  • 举例:
钓鱼时,一个人一条杆子,在杆子上挂一个铃铛,当铃铛响的时候则说明有鱼上够了需要进行处理,没响的时候可以忙其他的事情
  • 示图:

img

4、IO多路转接

  • 概念及介绍:
  1. 从流程图上看起来和阻塞IO类似,阻塞式等待数据准备就绪,得到数据结果后返回
  2. 实际上最核心在于IO多路转接能够同时等待多个文件描述符的就绪状态
  • 举例:
钓鱼时,一个人多条杆子,关注多条杆子的状态,当有一条杆子有动静时则可以进行相应的处理
  • 示图:

img

5、异步IO

  • 概念及介绍:
  1. 上述的四种IO模型都是同步IO,和异步IO最大的差别就是看是否需要主动参与到IO读写中去
  2. 异步IO由内核在数据拷贝完成时,再通知应用程序(而信号驱动IO是告诉应用程序何时可以开始拷贝数据)
  • 举例:
钓鱼时,老板雇了一个人,给了他一条杆子,当鱼桶装满时,雇佣的人再通知老板
  • 示图:

img

三、高级IO重要概念

1、同步通信 vs 异步通信

  1. 同步和异步关注的是消息通信机制
  2. 同步就是在发出一个调用时,在没有得到结果之前,该调用就不返回;但是一旦调用返回,就得到返回值了;换句话说,就是由调用者主动等待这个调用的结果
  3. 异步则是相反, 调用在发出之后,这个调用就直接返回了,所以没有返回结果;换句话说,当一个异步过程调用发出后,调用者不会立刻得到结果;而是在调用发出后, 被调用者通过状态、通知来通知调用者,或通过回调函数处理这个调用
注:进程多线程中的同步和互斥与这里的同步通信是完全不同的概念
  • 进程/线程同步:
进程/线程同步也是进程/线程之间直接的制约关系,是为完成某种任务而建立的两个或多个线程,这个线程需要在某些位置上协调他们的工作次序而等待、传递信息所产生的制约关系,尤其是在访问临界资源的时候

2、阻塞 vs 非阻塞

  1. 阻塞和非阻塞关注的是程序在等待调用结果(消息,返回值)时的状态
  2. 阻塞调用是指调用结果返回之前,当前线程会被挂起,调用线程只有在得到结果之后才会返回
  3. 非阻塞调用指在不能立刻得到结果之前,该调用不会阻塞当前线程

3、其他高级IO

非阻塞IO,纪录锁,系统V流机制, I/O多路转接(也叫I/O多路复用) ,readv和writev函数以及存储映射IO(mmap),这些统称为高级IO