我们在进行编程开发的时候,经常会涉及到同步、异步、阻塞、非阻塞、IO多路复用等概念,这几个概念有区别,但是有时候也容易混淆,下面记录下这几个概念的理解。

一、Unix网络编程中的五种IO模型

  • Blocking IO-阻塞IO
  • NoneBlocking IO-非阻塞IO
  • IO multiplexing-IO多路复用
  • signal driven IO-信号驱动IO
  • asynchronous IO-异步IO

由于信号驱动IO在实际使用中并不常见,所以下面只讨论剩下的四种IO模型。

在讨论之前先说明下IO发生时涉及到的对象和步骤,对于一个network IO,它会涉及到两个系统对象:

  • application:调用这个IO的进程
  • kernel:系统内核

经历的两个交互过程是:

  1. wait for data:等待数据准备
  2. copy data from kernel to user:将数据从内核拷贝到用户进程中

之所以会有同步、异步、阻塞和非阻塞这几种说法就是根据程序在这两个阶段的处理方式不同而产生的。了解了这些背景后,我们就分别针对四种IO模型进行讲解。

二、Blocking IO-阻塞IO

在linux中,默认情况下所有的socket都是blocking,一个典型的读操作流程大概如下图:


当用户进程调用了recvfrom这个系统调用,kernel就开始了IO的第一个阶段:准备数据。对于network IO来说,很多时候数据在一开始还没有到达(比如,还没有收到一个完整的UDP包),这个时候kernel就要等待足够的数据到来。而在用户进程这边,整个进程会被阻塞。当kernel一直等到数据准备好了,它就会将数据从kernel中拷贝到用户内存,然后kernel返回结果,用户进程才解除block的状态,重新运行起来。

所以,blocking IO的特点就是在IO执行的两个阶段都被block了。

三、NoneBlockingIO-非阻塞IO

linux下,可以通过设置socket使其变为non-blocking。当对一个non-blocking socket执行读操作时,流程是这个样子:

从图中可以看出,当用户进程发出recvfrom这个系统调用后,如果kernel中的数据还没有准备好,那么它并不会block用户进程,而是立刻返回一个结果(no datagram ready)。从用户进程角度讲 ,它发起一个操作后,并没有等待,而是马上就得到了一个结果。用户进程得知数据还没有准备好后,它可以每隔一段时间再次发送recvfrom操作。一旦kernel中的数据准备好了,并且又再次收到了用户进程的system call,那么它马上就将数据拷贝到了用户内存,然后返回。

所以,用户进程其实是需要不断的主动询问kernel数据好了没有。

四、myltiplexing-IO多路复用

I/O多路复用(multiplexing)是网络编程中最常用的模型,像我们最常用的select、epoll都属于这种模型。以select为例:

看起来它与blocking I/O很相似,两个阶段都阻塞。但它与blocking I/O的一个重要区别就是它可以等待多个数据报就绪(datagram ready),即可以处理多个连接。这里的select相当于一个“代理”,调用select以后进程会被select阻塞,这时候在内核空间内select会监听指定的多个datagram (如socket连接),如果其中任意一个数据就绪了就返回。此时程序再进行数据读取操作,将数据拷贝至当前进程内。由于select可以监听多个socket,我们可以用它来处理多个连接。

在select模型中每个socket一般都设置成non-blocking,虽然等待数据阶段仍然是阻塞状态,但是它是被select调用阻塞的,而不是直接被I/O阻塞的。select底层通过轮询机制来判断每个socket读写是否就绪。

当然select也有一些缺点,比如底层轮询机制会增加开销、支持的文件描述符数量过少等。为此,Linux引入了epoll作为select的改进版本。

五、asynchronous IO-异步IO

异步I/O在网络编程中几乎用不到,在File I/O中可能会用到:

这里面的读取操作的语义与上面的几种模型都不同。这里的读取操作(aio_read)会通知内核进行读取操作并将数据拷贝至进程中,完事后通知进程整个操作全部完成(绑定一个回调函数处理数据)。读取操作会立刻返回,程序可以进行其它的操作,所有的读取、拷贝工作都由内核去做,做完以后通知进程,进程调用绑定的回调函数来处理数据。

六、对比总结

6.1 阻塞和非阻塞

  • 阻塞调用会一直等待远程数据就绪再返回,即上面的阶段1会阻塞调用者,直到读取结束。
  • 而非阻塞无论在什么情况下都会立即返回,虽然非阻塞大部分时间不会被block,但是它仍要求进程不断地去主动询问kernel是否准备好数据,也需要进程主动地再次调用recvfrom来将数据拷贝到用户内存。

6.2 同步和异步

  • 同步方法会一直阻塞进程,直到I/O操作结束,注意这里相当于上面的阶段1,阶段2都会阻塞调用者。其中 Blocking IO - 阻塞IO,Nonblocking IO - 非阻塞IO,IO multiplexing - IO多路复用,signal driven IO - 信号驱动IO 这四种IO都可以归类为同步IO。
  • 而异步方法不会阻塞调用者进程,即使是从内核空间的缓冲区将数据拷贝到进程中这一操作也不会阻塞进程,拷贝完毕后内核会通知进程数据拷贝结束。

下图总结了之前说过的五种I/O模型:

https://www.jianshu.com/p/b8203d46895c

阻塞、非阻塞、同步、异步的区别相关推荐

  1. 阻塞/非阻塞与同步/异步的区别

    阻塞,非阻塞 同步,异步 阻塞与非阻塞最大的区别是调用方一直等待还是先去处理别的事情. 同步与异步最大的区别就是被调用方返回结果之前的这段时间内,调用方是否一直等待. 那么阻塞和同步,非阻塞和异步是一 ...

  2. 阻塞非阻塞与同步异步的区别?

    之前一直对阻塞非阻塞与同步异步这两对概念理解不深,总是把它们搞混.看了网上一些相关的解释之后,发现大家站在不同的角度得出了不同的理解,这个问题没有确切的答案,只能根据场景不同做出解释. 进程间的通信 ...

  3. 怎样理解阻塞非阻塞与同步异步的区别

    怎样理解阻塞非阻塞与同步异步的区别? 发现很多人对这两个概念往往混为一谈 6 条评论 分享 按投票排序 按时间排序 47 个回答 605赞同 反对,不会显示你的姓名 卢毅 ,Lyft full-sta ...

  4. 怎样理解阻塞非阻塞与同步异步的区别?

    发现很多人对这两个概念往往混为一谈(包括本人,不是很理解). 阻塞"与"非阻塞"与"同步"与"异步"不能简单的从字面理解,提供一个 ...

  5. 同步异步与阻塞非阻塞的区别 (不定时更新)

    同步异步与阻塞非阻塞的概念对于很多初学者来说是一个模糊的概念,其实我们的生活中存在着很多同步和异步的例子. 同步和异步关注的是消息通信机制 在计算机领域,同步就是指一个进程在执行某个请求的时候,若该请 ...

  6. 异步就是异步,根本就没有 异步非阻塞IO这个说法。阻塞 非阻塞,同步I/O 异步I/O 的区别

    先给大家安利一下这个 https://www.ibm.com/developerworks/cn/linux/l-async/ 里面关于 异步非阻塞IO 是错的. 异步就是异步,别扯 异步阻塞 异步非 ...

  7. 正确理解同步/异步和阻塞/非阻塞的区别:

    之前一直把异步和非阻塞混为一谈,在 了解BIO和NIO的区别时才发现了两者的差异,看了网上很多文章觉得说的总是差点意思,下面是个人理解: 1.同步 非同步 阻塞 非阻塞 概念 怎样理解阻塞非阻塞与同步 ...

  8. 同步/异步 阻塞/非阻塞区别

    我喜欢用自己的语言通过联系现实生活中的一些现象解释一些概念,当我能做到这一点时,说明我已经理解了这个概念.今天要解释的概念是:同步/异步与阻塞/非阻塞的区别. 这两组概念常常让人迷惑,因为它们都是涉及 ...

  9. 同步/异步与阻塞/非阻塞的区别

    这两组概念常常让人迷惑,因为它们都是涉及到IO处理,同时又有着一些相类似的地方. 首先来解释同步和 异步的概念,这两个概念与消息的通知机制有关. 举个 例子,比如我去银行办理业务,可能选择排队等候,也 ...

  10. Linux驱动学习9(同步/异步与阻塞/非阻塞的区别 )

    很多人对阻塞,非阻塞,同步,异步,并发,竞态的概念不是很清晰,今天我把我理解的用一个模型来说明一下这些概念. 首先建立一个模型: 我们去银行办理业务,屌丝的做法是: 1.银行未准备好,则一直排队,直到 ...

最新文章

  1. BigPipe:高性能的“流水线技术”网页
  2. android屏幕分享软件,ScreenStream(屏幕分享)
  3. 神经网络最容易忽略的问题影响了网络的性能(图像识别)
  4. 数据中心建设模式变革-- 如何采用EPC模式实现快速交付?
  5. HD 1213 How Many Tables(裸 并查集)
  6. 框架复习笔记-Java-案例:牛客网讨论社区
  7. java word转html 乱码 poi,java word转html poi
  8. [Matlab]函数表达式运算
  9. 华为可以看游戏时长吗_怎么测试华为手机玩游戏的帧率情况
  10. adb启动app_adb命令实战十三步
  11. 2、使用Spring框架能带来哪些好处
  12. 串口IO、定时器、回调函数
  13. 北京ICP经营许可证备案申请流程 电信业务经营许可办理
  14. WIN7下IIS的安装与配置
  15. 在写spring项目的时候,有时候需要写ApplicationContext,有时候不要写ApplicationContext
  16. linux mysql开发_Linux下MySQL数据库开发技术
  17. win7 c盘空间不足怎么扩大
  18. 2021-08-05,虾皮API,seller_info - 获得shopee店铺详情
  19. 数码相框(三、LCD显示文字)
  20. unity android 震动,unity 调用android的震动

热门文章

  1. 向上传递 java_Java向上转型向下转型
  2. 全场景解析!基于 Flink 的12个实时数仓生产实践
  3. 新场景 + 新应用,Flink 在机器学习领域的生产落地
  4. Android强大log框架Logger使用详解
  5. 为什么说 80% 的程序员都缺乏基本功?
  6. 多个pdf合并成一个pdf_多个PDF怎么合并?这些PDF合并方法很简单!
  7. python3数据结构菜鸟教程_Python3
  8. CPT自定义按钮导出(含参)
  9. 安装java目录不存在_从GitHub安装R packge - “'''在当前工作目录中不存在
  10. 基于京东家电商品知识图谱的自动问答系统(三) -- Java实现问答系统