一. 同步异步,阻塞非阻塞与数据二次拷贝

1. 同步异步: 任务的执行顺序上区分

  • 同步: 指一个任务, 只有当另一个任务返回后才能继续执行本任务
  • 异步: 指一个任务只是发起一个通知告诉另一个任务可以执行了, 然后就继续执行自身的任务

同步可以保证2个任务的执行顺序, 而异步不能

2. 阻塞和非阻塞: 线程等待状态上区分

  • 阻塞: 一个线程如果在等待另一个线程返回时, 自身处于挂起状态, 就是阻塞的
  • 非阻塞: 反之则是非阻塞

3. 同步阻塞和同步非阻塞

同步表示必须保证任务顺序, 阻塞表示线程等待另一个线程时是否会被挂起, 因此:

  • 同步非阻塞: 一个线程必须等待一个方法调用完毕才能继续执行接下来的任务, 且在等待过程中还可以执行其他方法, 则是同步非阻塞的
  • 同步阻塞: 一个线程必须等待一个方法调用完毕才能继续执行接下来的任务, 但是等待过程中自己处于挂起状态, 则是同步阻塞的

4. 数据由 socket 设备到用户态经过两次拷贝

用户进程在读/写外存(socket 设备)上的数据时, 数据先从 socket 拷贝到内核空间, 然后再从内核空间拷贝到用户空间.

二. Linux IO模型

IO 模型是针对, 数据从 socket 到内核空间, 再到用户空间这两次拷贝过程中, 用户线程的状态

同步IO模型

如下各种同步阻塞 IO 模型, 第二步 内核空间->内核空间 的数据拷贝都是阻塞的, 通过阻塞的方式, 实现数据拷贝和用户进程使用的同步

1. 同步阻塞IO

同步阻塞IO, 数据拷贝的两个阶段 (socket -> 内核, 内核 -> 用户)中, 用户进程都是处于阻塞状态.

2. 同步非阻塞IO

socket被设置成非阻塞的后

  • socket -> 内核空间 : 用户进程不会阻塞 (轮训操作系统)
    如果内核空间数据未拷贝完, 操作系统返回给用户进程一个错误码, 表示数据还未准备好. 此后用户进程要轮训询问操作系统数据拷贝进度.
  • 内核空间 -> 用户空间 : 用户进程阻塞
    数据到内核空间复制完毕后, 用户进程进入阻塞, 等待数据从内核空间复制到用户空间

所以,nonblocking IO的特点是用户进程需要不断的轮训询问kernel数据好了没有。

3. IO多路复用(NIO)

IO多路复用将同步非阻塞 IO 的到内核态拷贝中, 用户进行轮训操作系统改为操作系统自动轮训查看 socket 数据是否拷贝完毕, 且可以同时轮训多个 socket. (epool)
前置知识: 每个 socket 连接, 在 Linux 系统中会被表示成一个文件描述符(fd)
IO多路复用过程如下:

  1. socket -> 内接空间 (用户进程阻塞, 但可以提前返回, 且不必自己轮训拷贝状态)

    • 用户进程调用 select 系统调用后进入阻塞状态
    • 操作系统开始轮训所有 socket fd, 当]一个 socket fd 的数据可读/可写后(不用等到数据完全拷贝到内核空间), 在该 socket fd 上的 select 调用就会返回
  2. 内核空间 -> 用户空间 (用户进程阻塞)
    用户进程在 select 调用返回后变成就绪状态. 接着进行 recvFrom 调用, 将数据从内核空间拷贝到用户空间

IO多路复用主要解决服务器同时存在大量连接的情况, 是单线程处理多连接的模型;

上面提到的 select 和 epoll 主要有以下几个区别:

  1. select 的文件句柄数受限制, 最多能监听1024个 fd, 而 epoll 的 fd 个数没有限制
  2. select 采用轮训, fd 形成一个类似数组的结构. epoll 采用队列的数据结构, 对于是否有 fd 可读或可写, 直接查看对应的队列是否为空即可. 这是因为epoll只会对"活跃"的socket进行操作, 每个fd上配置一个回调函数, 只有fd可读或可写时才会出发回调函数(将自己加入相应的队列中), 其他idle状态句柄则不会,在这点上,epoll实现了一个"伪"AIO
  3. epool使用 mmap 加速内核与用户空间的消息传递。
    无论是 select,poll 还是 epoll 都需要内核把 FD 消息通知给用户空间,如何避免不必要的内存拷贝就很重要,在这点上,epoll是通过内核于用户空间mmap同一块内存实现的。

4. 信号驱动IO

  • socket -> 内核空间 (用户进程非阻塞)
    信号驱动式 I/O 第一步采用在 socket 上注册回调函数(信号处理函数)的方式, 让操作系统自行拷贝. 用户进程在此期间并不阻塞。当数据准备好时,进程会收到一个 SIGIO 信号,可以在信号处理函数中调用 IO 操作函数处理数据。
  • 内核空间 -> 用户空间 (用户进程阻塞)

异步IO模型

5. 异步非阻塞IO(AIO)

第一步和第二步, 用户进程都是非阻塞的
异步非阻塞 IO 是说, 用户发起 aio_read 操作之后, 函数立刻返回, 用户进程开始做其它工作, socket 数据复制到内核空间, 和内核空间复制到用户空间这两个步骤都是操作系统完成的. 两步完成后, 操作系统会给用户进程发送一个 signal 或执行一个基于线程的回调函数来完成这次 IO 处理过程,告诉它 read 操作完成了.

总结: 几种IO之间的区别

linux 五种 IO 模型相关推荐

  1. Linux五种IO模型性能分析

    转载:http://blog.csdn.net/jay900323/article/details/18141217     Linux五种IO模型性能分析 目录(?)[-] 概念理解 Linux下的 ...

  2. Windows五种IO模型性能分析和Linux五种IO模型性能分析

    Windows五种IO模型性能分析和Linux五种IO模型性能分析 http://blog.csdn.net/jay900323/article/details/18141217 http://blo ...

  3. 深入聊聊Linux五种IO模型

    一.相关概念讲解 1.同步与异步 同步就是一个任务的完成需要依赖另外一个任务时,只有等待被依赖的任务完成后,依赖的任务才能算完成,这是一种可靠的任务序列.要么成功都成功,失败都失败,两个任务的状态可以 ...

  4. linux 五种IO模型 简介

    Linux下主要的IO主要分为:阻塞IO(Blocking IO),非阻塞IO(Non-blocking IO),同步IO(Sync IO)和异步IO(Async IO). 同步:调用端会一直等待服务 ...

  5. 详解Linux 五种IO模型

    原文:https://www.jianshu.com/p/486b0965c296 上一篇 同步.异步.阻塞.非阻塞 已经通俗的讲解了,要理解同步.异步.阻塞与非阻塞重要的两个概念点了,没有看过的,建 ...

  6. Linux 五种IO模型

    想快速了解,看文末总结. 1 概念说明# 在进行解释之前,首先要说明几个概念: 用户空间和内核空间 进程切换 进程的阻塞 文件描述符 缓存 IO 1.1 用户空间与内核空间## 现在操作系统都是采用虚 ...

  7. linux五种IO模型

    为了更好的理解五种IO模型,我们先来说一下几个概念:同步,异步,阻塞和非阻塞. 同步和异步 这两个概念与消息的通知机制有关. 同步 所谓同步,就是在发出一个功能调用时,在没有得到结果之前,该调用就不返 ...

  8. 聊聊Linux 五种IO模型

    参考网络上相关内容即可: 五种IO模型 UNIX网络编程读书笔记:I/O模型(阻塞.非阻塞.I/O复用.信号驱动.异步)

  9. linux各种io模型,Linux五种IO模型

    Linux SendMail服务启动慢总结 在 CentOS release 6.6 上启动sendmail服务时发现服务启动过程非常慢,基本上要耗费3分多钟.有点纳闷:什么原因导致sendmail启 ...

最新文章

  1. 图片上传(加水印、缩略图、远程保存)的简单例子
  2. 学习python需要什么基础-学习python需要什么基础吗?老男孩Python
  3. iOS之“微信支付”开发流程
  4. 关于 .Net Core runtimeconfig 文件说明
  5. #3027. [Ceoi2004]Sweet 生成函数 + 组合数学
  6. 要多大内存才满足_佛龛的尺寸要多大?
  7. cubietruck 编译 linux,Cubietruck---1. ct的使用说明烧写及源码的编译
  8. 持续集成与持续部署实践_持续集成和部署的3个最佳实践
  9. JZOJ 1385. 直角三角形
  10. 性能监控工具yourkit的安装及eclipse、tomcat的集成
  11. Eureka安全访问
  12. sicily 1022. Train Problem
  13. 小黑小波比.coding的使用
  14. NHibernate Mapping文件中如何指定类的字节数组属性
  15. 经典CNN网络:VGG16-输入和输出
  16. arcgis出比例尺大小相同的图
  17. 分享几个比较通用的学习网站
  18. C#程序设计之windows应用程序设计基础
  19. 【Python】【教程】Python 教程
  20. 使用Golang开发手游服务器的感想

热门文章

  1. 如何从github上下载文件并运行
  2. MySQL联合索引原理解析
  3. 关系数据库、关系代数和关系运算
  4. Linux上的Shebang符号(#!)
  5. Git 上传代码到github上
  6. vscode的插件使用
  7. Linux 如何添加一个 Swap 文件
  8. Android进阶_Handler和Handler.Callback和Message
  9. ICA简介:独立成分分析
  10. 在TeXstuidio中如何设置XeLaTeX编译