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调用为例,它将完成或引起如下工作内容:
- 进程向操作系统请求外部数据
- 操作系统将外部数据加载到内核缓冲区
- 操作系统将数据从内核缓冲区拷贝到进程缓冲区
- 进程读取数据继续后面的工作
二、五种IO模型
1、阻塞IO
- 概念及介绍:
- 在进行IO读写时,系统调用会一直进行等待(不做其他的),直到内核将数据准备好,得到数据后才调用返回
- 阻塞IO是最常见的IO模型,所有的套接字函数调用默认都是阻塞方式
- 举例:
钓鱼时,一个人一条杆子,一动不动看着浮漂的动静,看是否有鱼上钩
- 示图:
2、非阻塞IO
- 概念及介绍:
- 如果内核还未将数据准备好,系统调用仍然会直接返回,并且返回EWOULDBLOCK错误码
- 非阻塞IO往往需要程序员循环的方式反复尝试读写文件描述符(查看数据是否准备好了),这个过程称为轮询,这对CPU来说是较大的浪费,一般只有特定场景下才使用
- 调用返回错误码时,说明此时数据没有准备好,那么就可以选择做一些其他的事情(非阻塞),过一段时间后再次进行访问查看数据是否准备好(轮询)
- 举例:
钓鱼时,一个人一条杆子,一会看着浮漂,没动静时就刷一会手机,隔段时间再看浮漂的动静
- 示图:
3、信号驱动IO
- 概念及介绍:
- 信号驱动IO模型并不主动去内核是否将数据准备好,这是并不高效的IO方式
- 它赋予关注的事件一套处理机制,在内核将数据准备好的时候,内核主动使用SIGIO信号通知应用程序进行IO操作
- 举例:
钓鱼时,一个人一条杆子,在杆子上挂一个铃铛,当铃铛响的时候则说明有鱼上够了需要进行处理,没响的时候可以忙其他的事情
- 示图:
4、IO多路转接
- 概念及介绍:
- 从流程图上看起来和阻塞IO类似,阻塞式等待数据准备就绪,得到数据结果后返回
- 实际上最核心在于IO多路转接能够同时等待多个文件描述符的就绪状态
- 举例:
钓鱼时,一个人多条杆子,关注多条杆子的状态,当有一条杆子有动静时则可以进行相应的处理
- 示图:
5、异步IO
- 概念及介绍:
- 上述的四种IO模型都是同步IO,和异步IO最大的差别就是看是否需要主动参与到IO读写中去
- 异步IO由内核在数据拷贝完成时,再通知应用程序(而信号驱动IO是告诉应用程序何时可以开始拷贝数据)
- 举例:
钓鱼时,老板雇了一个人,给了他一条杆子,当鱼桶装满时,雇佣的人再通知老板
- 示图:
三、高级IO重要概念
1、同步通信 vs 异步通信
- 同步和异步关注的是消息通信机制
- 同步就是在发出一个调用时,在没有得到结果之前,该调用就不返回;但是一旦调用返回,就得到返回值了;换句话说,就是由调用者主动等待这个调用的结果
- 异步则是相反, 调用在发出之后,这个调用就直接返回了,所以没有返回结果;换句话说,当一个异步过程调用发出后,调用者不会立刻得到结果;而是在调用发出后, 被调用者通过状态、通知来通知调用者,或通过回调函数处理这个调用
注:进程多线程中的同步和互斥与这里的同步通信是完全不同的概念
- 进程/线程同步:
进程/线程同步也是进程/线程之间直接的制约关系,是为完成某种任务而建立的两个或多个线程,这个线程需要在某些位置上协调他们的工作次序而等待、传递信息所产生的制约关系,尤其是在访问临界资源的时候
2、阻塞 vs 非阻塞
- 阻塞和非阻塞关注的是程序在等待调用结果(消息,返回值)时的状态
- 阻塞调用是指调用结果返回之前,当前线程会被挂起,调用线程只有在得到结果之后才会返回
- 非阻塞调用指在不能立刻得到结果之前,该调用不会阻塞当前线程
3、其他高级IO
非阻塞IO,纪录锁,系统V流机制, I/O多路转接(也叫I/O多路复用) ,readv和writev函数以及存储映射IO(mmap),这些统称为高级IO