五种IO模型与高级IO


前言

IO 技术的发展始终围绕 “提升性能、降低开销” 的目标:基本 IO 模型解决数据交互的基础问题,而高级 IO 技术(如多路复用、零拷贝、异步 IO)则通过系统层面的优化,突破传统 IO 的性能瓶颈。


一、IO基础概念

I/O(input/output)也就是输入和输出,在著名的冯诺依曼体系结构当中,将数据从输入设备拷贝到内存就叫做输入,将数据从内存拷贝到输出设备就叫做输出。
在这里插入图片描述

  • 对文件进行的读写操作本质就是一种IO,文件IO对应的外设就是磁盘。
  • 对网络进行的读写操作本质也是一种IO,网络IO对应的外设就是网卡。

IO=等+拷贝,所以定义上的IO比较慢,其实都体现在了等这一步上面。
IO效率高:单位时间内,传输的数据越多,效率就越高

二、五种IO模型

IO的过程其实和钓鱼是非常类似的。

钓鱼的过程同样分为“等”和“拷贝”两个步骤,只不过这里的“等”指的是等鱼上钩,“拷贝”指的是当鱼上钩后将鱼从河里“拷贝”到我们的鱼桶当中。
IO时“等”消耗的时间往往比“拷贝”消耗的时间多,钓鱼也恰好符合这个特点,钓鱼时我们大部分时间都在等鱼上钩,而当鱼上钩后只需要一瞬间就能将鱼“拷贝”上来。

在谈论高效的IO之前,我们先来看看什么样的钓鱼方式才是高效的。

下面给出五个人的钓鱼方式:

  1. 张三:拿了1个鱼竿,将鱼钩抛入水中后就死死的盯着浮漂,什么也不做,当有鱼上钩后就挥动鱼竿将鱼钓上来。----阻塞IO
  2. 李四:拿了1个鱼竿,将鱼钩抛入水中后就去做其他事情,然后定期观察浮漂,如果有鱼上钩则挥动鱼竿将鱼钓上来,否则继续去做其他事情。----非阻塞IO
  3. 王五:拿了1个鱼竿,将鱼钩抛入水中后在鱼竿顶部绑一个铃铛,然后就去做其他事情,如果铃铛响了就挥动鱼竿将鱼钓上来,否则就根本不管鱼竿。----信号驱动IO
  4. 赵六:拿了100个鱼竿,将100个鱼竿抛入水中后就定期观察这100个鱼竿的浮漂,如果某个鱼竿有鱼上钩则挥动对应的鱼竿将鱼钓上来。—多路转接,多路复用
  5. 田七:田七是一个有钱的老板,他给了自己的司机一个桶、一个电话、一个鱼竿,让司机去钓鱼,当鱼桶装满的时候再打电话告诉田七拿鱼,而田七自己则开车去做其他事情去了。----异步IO

张三、李四、王五的钓鱼效率是否一样?为什么?
张三、李四、王五的钓鱼效率本质上是一样的。
首先他们的钓鱼方式都是一样的,都是先等鱼上钩,然后再将鱼钓上来。
其次,因为他们每个人都是拿的一根鱼竿,当河里有鱼来咬鱼钩时,这条鱼咬哪一个鱼钩的概率都是相等的。
因此张三、李四、王五他们三个人的钓鱼的效率是一样的,他们只是等鱼上钩的方式不同而已,张三是死等,李四是定期检测浮漂,而王五是通过铃铛来判断是否有鱼上钩。
需要注意的是,这里问的是他们的钓鱼效率(IO事件效率)是否是一样的,而不是问他们整体谁做的事最多,如果说整体做事情的量的话,那一定是王五做得最多,李四次之,张三最少。

阻塞:IO条件不具备,等待条件就绪。
非阻塞:IO条件不具备,出错返回
两者的不同仅仅体现在等待方式不同上,因此在很多教材里面都提到非阻塞IO效率高是不准确的,只能说非阻塞在同样的时间里做了更多其它事情,而在IO这件事上和阻塞是没有区别的!!

IO=等+拷贝
同步IO:凡是参与IO等或者拷贝一个或者多个阶段
异步IO:发起IO或者IO工作流和自己的工作流无关

因此可以得出阻塞,非阻塞,信号驱动,多路是同步IO(其实有关同步和异步IO的分类是有争议的,不过当前就这样子定义下来)。并且高效IO就是减少单位时间内等的比重

阻塞IO

  • 阻塞 IO: 在内核将数据准备好之前, 系统调用会一直等待. 所有的套接字, 默认
    都是阻塞方式.

阻塞 IO 是最常见的 IO 模型.
在这里插入图片描述

非阻塞IO

  • 非阻塞 IO: 如果内核还未将数据准备好, 系统调用仍然会直接返回, 并且返回
    EWOULDBLOCK 错误码.

非阻塞 IO 往往需要程序员循环的方式反复尝试读写文件描述符, 这个过程称为轮询. 这对 CPU 来说是较大的浪费, 一般只有特定场景下才使用.
在这里插入图片描述

信号驱动IO

  • 信号驱动 IO:内核将数据准备好的时候,使用 SIGIO信号通知应用程序进行 IO操作.
    在这里插入图片描述

多路转接

  • IO 多路转接: 虽然从流程图上看起来和阻塞 IO 类似. 实际上最核心在于 IO 多
    路转接能够同时等待多个文件描述符的就绪状态.

异步IO

  • 异步 IO: 由内核在数据拷贝完成时, 通知应用程序(而信号驱动是告诉应用程序
    何时可以开始拷贝数据).
    在这里插入图片描述

任何 IO 过程中, 都包含两个步骤. 第一是等待, 第二是拷贝. 而且在实际的应用
场景中, 等待消耗的时间往往都远远高于拷贝的时间. 让 IO 更高效, 最核心的办法就
是让等待的时间尽量少.

三、高级IO概念

同步通信和异步通信

进程参与进去的通信就是同步通信,进程发起通信后但不参与的就是异步通信

阻塞和非阻塞

阻塞和非阻塞关注的是程序在等待调用结果(消息、返回值)时的状态。

  • 阻塞调用是指调用结果返回之前,当前线程会被挂起,调用线程只有在得到结果之后才会返回。
  • 非阻塞调用指在不能立刻得到结果之前,该调用不会阻塞当前线程。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值