前言

我们经常看到阻塞/非阻塞,同步/异步这两组容易混淆的概念,那么该如何区分呢?

用户空间和内核空间

内核是操作系统的核心,可以访问底层硬件设备的所有权限。为了保护内核安全,就把操作系统的内存空间分为:内核空间和用户空间。

这两个空间是独立的。

使用 TCP 发送数据时,需要先将数据从用户空间拷贝到内核空间,再用内核操作将数据从内核空间发出。

当我们使用 TCP 读取数据时,先在内核空间准备好,再从内核空间拷贝到用户空间使用。

IO 五种模型

IO 五种模型分别是 :阻塞型 IO、非阻塞 IO、IO 多路复用、信号驱动 IO、异步 IO。

阻塞型 IO

用户进程发起请求时,阻塞到数据拷贝到用户空间才为止。

阻塞 IO 在这两个阶段都是阻塞的。(发送数据拷贝到内核空间是阻塞的,内核空间拷贝到用户空间,返回数据也是阻塞的)

非阻塞 IO

用户进程不断询问内核,数据准备好了吗?直到内核说准备好了,将数据从内核空间拷贝到用户空间。

非阻塞IO第一阶段不阻塞(用户进程询问内核,会立即得到回应,不阻塞 ),第二阶段会阻塞(要等着内核空间拷贝数据到用户空间并返回)。

IO 多路复用

多个 IO 操作共同使用一个 selector(选择器)去询问哪些 IO 需要的数据准备好了,selector 负责通知那些准备好的 IO,那些 IO 再自己去请求内核数据。

IO 多路复用,第一阶段会阻塞到 slector 上,第二阶段拷贝数据也会阻塞。

信号驱动 IO

用户进程发起读取请求前先注册一个信号给内核说明自己需要什么数据,这个注册立刻返回。等内核准备好了,主动通知用户进程,用户进程再读取数据,等待数据从内核空间拷贝到用户空间再返回。

信号驱动 IO,第一阶段不阻塞(注册信号会立刻返回),第二阶段阻塞(需要等待数据从内核空间拷贝到用户空间)。

异步 IO

用户进程读取数据请求后立马返回,当数据从内核空间拷贝到用户空间再通知用户直接使用数据。

异步IO,两个阶段都不阻塞。

总结

阻塞和非阻塞

阻塞:调用结果返回之前,当前线程会被挂起,直到调用结果返回。

非阻塞:不能立即得到结果之前,当前线程不会被挂起,可以做其他事。

阻塞调用后必须等着结果返回,非阻塞调用之后爱干什么干什么

同步与异步

同步:调用者会被阻塞,直到 IO 操作完成,调用的结果随着请求的结束返回。

异步:调用者不会被阻塞,调用的结果不随着请求的结束而返回,而是通过通知或者回调函数的形式返回。

也就是说,阻塞/非阻塞,更关心的是当前线程是不是被挂起。而同步/异步,更关心的是调用结果是不是随着请求结束而返回。

所以 IO 五种模型中,阻塞IO、非阻塞IO、多路复用IO、信号驱动IO都是同步IO,只有最后一个才是异步IO。

最新文章

  1. JavaScript格式化日期
  2. 查看iOS模拟器应用的沙箱文件
  3. 【转】C# 解析JSON格式数据
  4. 访问修饰符internal
  5. Gym 100507A About Grisha N. (水题)
  6. Linux 命令 - kill: 向进程发送信号
  7. bzoj2821作诗
  8. JavaIO学习总结一
  9. JDBC插入百万数据,不到5秒!
  10. 联想G480安装CentOS电缆驱动器
  11. Delphi在Vasta/win 7下通过UAC控制
  12. 聊聊RocksDB Compact
  13. tensorflow softmax应用
  14. mvn mybatis-generator:generate postgresql
  15. JavaScript 执行环境、作用域、内存管理及垃圾回收机制
  16. Ubuntu上hi3531交叉编译环境arm-hisiv100nptl-linux搭建过程
  17. 理解 Memory barrier(内存屏障)无锁环形队列
  18. 100-days: twenty-four
  19. 使用nifi采集数据要配置的环境
  20. dp算法之平安果路径问题c++

热门文章

  1. ceph的rbd备份软件ceph-backup
  2. apiAutoTest-更新2020/11/23
  3. C语言中的const用法
  4. mysql学习笔记1(mysql的基本架构)
  5. java开发两年了,连个java代理模式都摸不透,你怎么跳槽涨薪?
  6. 面试阿里,字节,美团必看的Spring的Bean管理详解
  7. python 中 try...finally... 的优雅实现
  8. 借助Mac自带的强大的搜索功能,如何快速搜索打开Tuxera Disk Manager
  9. Java基础教程——Object类
  10. CentOS下设置ipmi