转载自:http://chuansong.me/n/2124760

几年前曾写过一篇描写同步/异步以及阻塞/非阻塞的文章,最近再回头看,还存在一些理解和认知误区,于是重新整理一下相关的概念,希望对网络编程的同行能有所启发。

同步与异步

首先来解释同步和异步的概念,这两个概念与消息的通知机制有关。

举个例子,比如一个用户去银行办理业务,他可以自己去排队办理,也可以叫人代办,办完之后再告知用户结果。对于要办理这个银行业务的人而言,自己去办理是同步方式,而别人代办完毕再告知则是异步方式。

两者的区别在于,同步的方式下,操作者主动完成了这件事情;而异步方式下,调用指令发出后,操作马上就返回了,操作者并不能马上知道结果,而是等待所调用的异步过程(在这个例子中是帮忙代办的人)处理完毕之后,再通过通知手段(在代码中通常是回调函数)来告诉操作者结果。

在上图的异步 IO 模型中,应用程序调用完 aio_read 之后,不论是否有数据可读,这个操作都会马上返回,这个过程相当于这个例子中委托另一个人去帮忙代办银行业务的过程,当数据读完拷贝到用户内存之后,会发一个信号通知原进程告诉读数据操作已经完成(而不仅仅是有数据可读)。

阻塞与非阻塞

接着解释阻塞与非阻塞的概念。这两个概念与程序处理事务时的状态有关。

同样用前面的例子,当真正执行办理业务的人去办理银行业务时,前面可能已经有人排队等候。如果这个人一直从排队到办理完毕,中间都没有做过其他的事情,那么这个过程就是阻塞的,这个人当前只在做这么一件事情。

在上图中,应用程序发起 recvfrom 操作之后,要等待数据拷贝成功才能返回。整个过程中,不能做其它的操作,这个就是典型的阻塞 IO。

反之,如果这个人发现前面排队的人不少,于是选择了出去逛逛,过了一会再回来看看有没有轮到他的号被叫到,如果没有又继续出去逛,过一阵再回来看看……如此以往,这个过程就是非阻塞的。因为处理这个事情的人,在这整个过程中,并没有做到除了这件事之外不做别的事情,他的做法是反复的过来检测,如果还没有完成就下一次再次尝试完成这件事情。

上图与前面阻塞 IO 图的区别在于,当没有数据可读时,同样的 recvfrom 操作返回了错误码,表示当前没有可读数据。换言之,即使没有数据也不会一直让这个应用阻塞在这个调用上,这就是非阻塞 IO。

到了这里,可以先简单的小结一下这两组概念

  • 阻塞与非阻塞:区别在于完成一件事情时,当事情还没有完成时,处理这件事情的人除此之外不能再做别的事情;

  • 同步与异步:是自己去做这件事情,还是等别人做好了来通知有结果,然后再自己去拿结果。注意这里说的是拿结果,如果只是别人告诉你可以做某事,然后自己去操作,这种情况下也是同步的操作,在后面多路复用I/O中会进行阐述。

可见,两组概念不是一个维度的概念。我们把需要办理银行业务的人称为 A,把代办理的人称为 B,那么在 A 委托 B 办理业务的情况下,假设 A 在交代 B 帮忙办事之后,A 就去做别的事情,那么 A 并不存在针对办理银行业务这件事情而言是阻塞还是非阻塞,办理事务时阻塞与否,是针对真正需要办理这件事情的人,也就是这个例子里的 B。

与多路复用 I/O 的联系

前几年写这篇文章时,将多路复用 I/O 类的 select/poll 等和异步操作混为一谈,在这里特别做一些补充说明。

在以前笔者包括不少同行的理解中,就这个例子而言,列举下面情况,当去办理业务的人,需要排队时通常都会先去取号,拿到一个纸条的号码,然后等待银行叫号。在那个例子里面,曾经将银行叫号理解成 select 操作,把纸条比作向 select 注册的回调函数,一旦可以进行操作的条件满足,就会根据这个回调函数来通知办理人,然后办理人再去完成工作,因此 select 等多路复用操作是异步的行为。

但上面这种理解最大的错误在于,同步与异步的区别在于是不是要求办理者自己来完成,所有需要自己完成的操作都是同步操作,不管是注册了一个回调(这里的叫号小纸条)等待回调你,还是自己一直阻塞等待。

在上例中,虽然对需要办理业务的人而言,通过叫号小纸条,他可以等待银行的办理通知。等待的同时可以去别的事情,比如浏览手机上网,但只要可以办理该业务的条件满足,真正叫到号可以办理业务时,办理者是需要自己去完成办理的。

换言之,在完成一件事情时,需要区分处理两种状态:一是这个事情是不是可以做了(条件满足的消息,如 select 告诉你某个文件描述符可读),另外一个是否完成了这件事情(如调用 read/write 完成 IO 操作)。多路复用 IO 记录下来有哪些人在等待消息的通知,在条件满足时负责通知办理者,而完成这件事情还是需要办理者自己去完成。只要是自己去完成的操作,都是同步的操作

UNP 的 6.2 节中,最后对异步与同步做的总结非常准确。

POSIX defines these two terms as follows:

A synchronous I/O operation causes the requesting process to be blocked until that I/O operation completes.

An asynchronous I/O operation does not cause the requesting process to be blocked.

Using these definitions, the first four I/O models—blocking, nonblocking, I/O multiplexing, and signal-driven I/O—are all synchronous because the actual I/O operation (recvfrom) blocks the process. Only the asynchronous I/O model matches the asynchronous I/O definition.

转载于:https://www.cnblogs.com/wsnb/p/5132080.html

深入理解同步/异步与阻塞/非阻塞区别 (转)相关推荐

  1. 理解同步异步、阻塞与非阻塞

    "阻塞"与"非阻塞"与"同步"与"异步"不能简单的从字面理解,提供一个从分布式系统角度的回答. 1.同步与异步 同步和异 ...

  2. 异步/同步、阻塞/非阻塞的理解

    异步/同步.阻塞/非阻塞的理解 [同步和异步] 通俗的讲: 同步是指:发送方发出数据后,等接收方发回响应以后才发下一个数据包的通讯方式.  异步是指:发送方发出数据后,不等接收方发回响应,接着发送下个 ...

  3. 一篇文章理解 同步异步、阻塞非阻塞

    前述 同步异步,阻塞非阻塞是一些非常常见的概念,但是对于开发者来说往往是用到了很难说清楚. 笔者专门整理了下这方面的概念,作此文以记之. 这部分内容可能存在一些争议,如有不同意见欢迎评论交流. 概念 ...

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

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

  5. 彻底理解同步异步阻塞与非阻塞

    彻底理解同步异步阻塞与非阻塞 前言 用户空间 内核空间 系统调用 用户态 内核态 系统IO 阻塞非阻塞 同步异步 前言 最近有同事问我同步异步与阻塞非阻塞有什么区别,后来发现很多同事不能区分这些概念. ...

  6. 15分钟读懂进程线程、同步异步、阻塞非阻塞、并发并行,太实用了!

    作者:Martin cnblogs.com/mhq-martin/p/9035640.html 基本概念 1 进程和线程 进程(Process): 是Windows系统中的一个基本概念,它包含着一个运 ...

  7. 迄今为止把同步/异步/阻塞/非阻塞/BIO/NIO/AIO讲的这么清楚的好文章(快快珍藏)...

    常规的误区 假设有一个展示用户详情的需求,分两步,先调用一个HTTP接口拿到详情数据,然后使用适合的视图展示详情数据. 如果网速很慢,代码发起一个HTTP请求后,就卡住不动了,直到十几秒后才拿到HTT ...

  8. 【面试】迄今为止把同步/异步/阻塞/非阻塞/BIO/NIO/AIO讲的这么清楚的好文章(快快珍藏)...

    网上有很多讲同步/异步/阻塞/非阻塞/BIO/NIO/AIO的文章,但是都没有达到我的心里预期,于是自己写一篇出来. 常规的误区 假设有一个展示用户详情的需求,分两步,先调用一个HTTP接口拿到详情数 ...

  9. 迄今为止把同步/异步/阻塞/非阻塞/BIO/NIO/AIO讲的这么清楚的好文章

    来源:编程新说 网上有很多讲同步/异步/阻塞/非阻塞/BIO/NIO/AIO的文章,但是都没有达到我的心里预期,于是自己写一篇出来. 常规的误区 假设有一个展示用户详情的需求,分两步,先调用一个HTT ...

  10. 面试必会系列 - 5.1 网络BIO、NIO、epoll,同步/异步模型、阻塞/非阻塞模型,你能分清吗?

    本文已收录至 Github(MD-Notes),若博客中图片模糊或打不开,可以来我的 Github 仓库,包含了完整图文:https://github.com/HanquanHq/MD-Notes,涵 ...

最新文章

  1. C# System.Reflection (反射)
  2. php添加管理员页面完整代码,php – Opencart管理员端的空白页面
  3. pycharm调试过程中出现跳过某行的现象解决办法(不要在调试过程中修改代码!)
  4. SQL SERVER中一些常见性能问题的总结
  5. 设计模式适配器模式_21世纪的设计模式:适配器模式
  6. java浏览文件夹_一个用java实现简单的文件浏览器
  7. 理论基础 —— 队列
  8. openjdk替换java_ubuntu中将java环境由安装版的openjdk替换为Oracle的jdk
  9. 随机增量法:bzoj 1336 bzoj 1337 最小圆覆盖
  10. Sqlserver数据类型精解
  11. ffmpeg实现摄像头拉流_ffmpeg推流及拉流
  12. 电子系统中的品质因数
  13. 《Mybatis 手撸专栏》第10章:使用策略模式,调用参数处理器
  14. 程序员的办公好选择:工作效率翻倍,游戏也能超神
  15. “丧心病狂” kite
  16. mysql插入特殊汉字、字符报错
  17. 元宇宙如何改写人类社会生活
  18. 用 Flask 来写个轻博客 (1) — 创建项目
  19. iso映像_如何在Windows 7中刻录ISO映像
  20. PDF的加密解密,解密后随便怎么玩

热门文章

  1. 湖科大计算机科学与技术,湖南科技大学计算机科学与工程学院前来我院进行访问与交流...
  2. Git学习系列之Git基本操作推送项目(图文详解)
  3. jsp无法提交nicEdit中的内容的解决办法
  4. 精彩案例:一碗牛肉面的思考
  5. 【黑金动力社区】【bf531 体验板教程】第六章 可编程标志口(八)
  6. C# 与 C 和 C++ 比较
  7. 读书笔记-----Oracle字符处理函数列表
  8. LEARNING TO EXPLORE USING ACTIVE NEURAL SLAM
  9. TX2系统备份与恢复
  10. cpp存储类型说明符(storage class specifier)