同步与异步&阻塞与非阻塞-各类解释

最近看到软文,总结了下同步与异步&阻塞与非阻塞的区别,因为习惯性的喜欢看文章后面的评论。发现有对原文做者的说法表示了质疑。让我这个小菜也不知道,做者的说法到底准不许确,因而乎开始在网上找找是否有“权威”通俗易懂的说法。不得不说,人民群众的力量是强大的,从不一样的层级论述了——同步、异步、阻塞和非阻塞。现摘抄几个本身以为理解到位的说法。html

   原1:http://my.oschina.net/haoran100/blog/707197git

   内容:编程

    

摘要微信

一直为同步异步,阻塞非阻塞概念所困扰,特定总结了下,原来是这么个意思网络

一直为同步异步,阻塞非阻塞概念所困扰,特定总结了下多线程

1、同步与异步的区别

一、概念介绍

  • 同步:所谓同步是一个服务的完成须要依赖其余服务时,只有等待被依赖的服务完成后,依赖的服务才能算完成,这是一种可靠的服务序列。要么成功都成功,失败都失败,服务的状态能够保持一致。并发

  • 异步:所谓异步是一个服务的完成须要依赖其余服务时,只通知其余依赖服务开始执行,而不须要等待被依赖的服务完成,此时该服务就算完成了。至于被依赖的服务最终是否真正完成,没法肯定,因此它是不可靠的服务序列。异步

二、消息通知

  • 同步:当一个同步调用发出后,调用者要一直等待返回消息(或者调用结果)通知后,才能进行后续的执行;socket

  • 异步:当一个异步过程调用发出后,调用者不能马上获得返回消息(结果)。实际处理这个调用的部件在完成后,经过消息回调来通知调用者是否调用成功。async

PS:调用者获取依赖服务异步回调结果通常有两种方式:
一种是主动去轮训查询异步回调的结果,
一种调用依赖服务时传入一个callback方法或者回调地址,依赖服务完成以后去调用callback通知调用者。
通常状况,这两种方式都要支持才是一种良好的异步回调设计方法。

三、场景比喻

小明去买奶茶,可能会有两种方式

  • 小明点单交钱,而后等着取奶茶;
  • 小明点单交钱,而后奶茶妹给了小明一个小票,等小明的奶茶作好了,再告诉小明来取;
第一种方式就是同步,就等着奶茶妹作好奶茶,奶茶作好以后,小明拿到奶茶才算完成整个任务

第二种方式就是异步,奶茶妹给了小明一个小票,小明就算完成了。至于最后奶茶作好没有,反正奶茶妹会告诉小明的,那是后面的事情了。

四、总结

同步与异步着重点在消息通知的方式,也就是调用结果通知的方式。结合场景就是,拿到奶茶的方式。

2、阻塞与非阻塞的区别

一、概念介绍

  • 阻塞:阻塞调用是指调用结果返回以前,当前线程会被挂起,一直处于等待消息通知,不可以执行其余业务。函数只有在获得结果以后才会返回。
阻塞调用和同步调用不一样的。
对于同步调用来讲,不少时候当前线程可能仍是激活的,只是从逻辑上当前函数没有返回而已,此时,这个线程可能也会处理其余的消息。

还有一点,在这里先扩展下:
1.若是这个线程在等待当前函数返回时,仍在执行其余消息处理,那这种状况就叫作同步非阻塞;
2.若是这个线程在等待当前函数返回时,没有执行其余消息处理,而是处于挂起等待状态,那这种状况就叫作同步阻塞;

因此同步的实现方式会有两种:同步阻塞、同步非阻塞;同理,异步也会有两种实现:异步阻塞、异步非阻塞;
对于阻塞调用来讲,则当前线程就会被挂起等待当前函数返回;
  • 非阻塞:非阻塞和阻塞的概念相对应,指在不能马上获得结果以前,该函数不会阻塞当前线程,而会马上返回。
    虽然表面上看非阻塞的方式能够明显的提升CPU的利用率,可是也带了另一种后果就是系统的线程切换增长。
    增长的CPU执行时间能不能补偿系统的切换成本须要好好评估。

二、场景比喻

仍是小明去买奶茶,可能会有两种方式

  • 2.一、小明点单交钱,而后等着取奶茶; ``` 一、小明在等着取奶茶的时候呢,啥都不干,就等着; 小明等奶茶的行为就叫作阻塞,小明在等奶茶的时候,阻塞了!而这种方式又叫作同步阻塞。

二、小明在等着取奶茶的时候呢,翻出手机,一会翻翻微信朋友圈,一会瞅瞅奶茶妹有没有作好奶茶; 小明这种行为就叫作非阻塞,由于没有阻塞在等奶茶这件事情上。而这种方式又叫作同步非阻塞。

- 2.二、小明点单交钱,而后奶茶妹给了小明一个小票,等小明的奶茶作好了,再告诉小明来取;

一、奶茶妹给了小明一个小票,而后小明仍是傻等着; 小明这种拿到票还傻等着的行为,就叫阻塞。而这种行为,又叫作异步阻塞!这种最傻了。

二、奶茶妹给了小明一个小票,而后小明翻出手机一直刷朋友圈, 过了一下子奶茶妹说小明你的奶茶好了,过来拿,小明才放下手机去拿奶茶。 这种方式就叫作非阻塞,又叫着异步非阻塞! ```

三、总结

阻塞与非阻塞的着重点在于当前线程等待消息返回的行为。换成场景就是,小明等奶茶的行为。

3、大总结

  • 一、同步阻塞:小明啥都不干等奶茶。
  • 二、同步非阻塞:小明一边玩手机一边等奶茶。
  • 三、异步阻塞:小明拿着小票啥都不干等着奶茶妹告诉他奶茶好了
  • 四、异步非阻塞:小明拿着小票玩着手机等着奶茶妹告诉他奶茶好了

 

 

原2:知乎 https://www.zhihu.com/question/19732473

说2.1:

做者:严肃
连接:https://www.zhihu.com/question/19732473/answer/20851256
来源:知乎
著做权归做者全部。商业转载请联系做者得到受权,非商业转载请注明出处。
 

阻塞”与"非阻塞"与"同步"与“异步"不能简单的从字面理解,提供一个从分布式系统角度的回答。
1.同步与异步
同步和异步关注的是消息通讯机制 (synchronous communication/ asynchronous communication)
所谓同步,就是在发出一个*调用*时,在没有获得结果以前,该*调用*就不返回。可是一旦调用返回,就获得返回值了。
换句话说,就是由*调用者*主动等待这个*调用*的结果。

而异步则是相反,*调用*在发出以后,这个调用就直接返回了,因此没有返回结果。换句话说,当一个异步过程调用发出后,调用者不会马上获得结果。而是在*调用*发出后,*被调用者*经过状态、通知来通知调用者,或经过回调函数处理这个调用。

典型的异步编程模型好比Node.js

举个通俗的例子:
你打电话问书店老板有没有《分布式系统》这本书,若是是同步通讯机制,书店老板会说,你稍等,”我查一下",而后开始查啊查,等查好了(多是5秒,也多是一天)告诉你结果(返回结果)。
而异步通讯机制,书店老板直接告诉你我查一下啊,查好了打电话给你,而后直接挂电话了(不返回结果)。而后查好了,他会主动打电话给你。在这里老板经过“回电”这种方式来回调。

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

阻塞调用是指调用结果返回以前,当前线程会被挂起。调用线程只有在获得结果以后才会返回。
非阻塞调用指在不能马上获得结果以前,该调用不会阻塞当前线程。

仍是上面的例子,
你打电话问书店老板有没有《分布式系统》这本书,你若是是阻塞式调用,你会一直把本身“挂起”,直到获得这本书有没有的结果,若是是非阻塞式调用,你无论老板有没有告诉你,你本身先一边去玩了, 固然你也要偶尔过几分钟check一下老板有没有返回结果。
在这里阻塞与非阻塞与是否同步异步无关。跟老板经过什么方式回答你结果无关。


若是是关心blocking IO/ asynchronous IO, 参考 Unix Network Programming View Book

说2.2:

做者:星辰大海
连接:https://www.zhihu.com/question/19732473/answer/26101328
来源:知乎
著做权归做者全部。商业转载请联系做者得到受权,非商业转载请注明出处。
 

一讲到网络编程的I/O模型,总会涉及到这几个概念。问了不少人,没几个能清晰地讲出他们之间的区别联系,甚至在网络上也有不少不一样的观点,也不知是中国文字释义的博大精深,仍是原本这几个概念就是绕人不倦。今天我也来给你们讲解一下我对这几个概念的理解。

既然网络上众说纷纭,不如找个权威参考一下,这个权威就是《UNIX网络编程:卷一》第六章——I/O复用。书中向咱们说起了5种类UNIX下可用的I/O模型:

  • 阻塞式I/O;

  • 非阻塞式I/O;

  • I/O复用(select,poll,epoll...);

  • 信号驱动式I/O(SIGIO);

  • 异步I/O(POSIX的aio_系列函数);

阻塞式I/O模型:默认状况下,全部套接字都是阻塞的。怎么理解?先理解这么个流程,一个输入操做一般包括两个不一样阶段:

(1)等待数据准备好;
(2)从内核向进程复制数据。


对于一个套接字上的输入操做,第一步一般涉及等待数据从网络中到达。当全部等待分组到达时,它被复制到内核中的某个缓冲区。第二步就是把数据从内核缓冲区复制到应用程序缓冲区。 好,下面咱们以阻塞套接字的recvfrom的的调用图来讲明阻塞

标红的这部分过程就是阻塞,直到阻塞结束recvfrom才能返回。

非阻塞式I/O: 如下这句话很重要:进程把一个套接字设置成非阻塞是在通知内核,当所请求的I/O操做非得把本进程投入睡眠才能完成时,不要把进程投入睡眠,而是返回一个错误。看看非阻塞的套接字的recvfrom操做如何进行

能够看出recvfrom老是当即返回。

I/O多路复用:虽然I/O多路复用的函数也是阻塞的,可是其与以上两种仍是有不一样的,I/O多路复用是阻塞在select,epoll这样的系统调用之上,而没有阻塞在真正的I/O系统调用如recvfrom之上。如图

信号驱动式I/O:用的不多,就不作讲解了。直接上图

异步I/O:这类函数的工做机制是告知内核启动某个操做,并让内核在整个操做(包括将数据从内核拷贝到用户空间)完成后通知咱们。如图:

注意红线标记处说明在调用时就能够立马返回,等函数操做完成会通知咱们。

等等,你们必定要问了,同步这个概念你怎么没涉及啊?别急,您先看总结。 其实前四种I/O模型都是同步I/O操做,他们的区别在于第一阶段,而他们的第二阶段是同样的:在数据从内核复制到应用缓冲区期间(用户空间),进程阻塞于recvfrom调用。相反,异步I/O模型在这两个阶段都要处理。

再看POSIX对这两个术语的定义:

  • 同步I/O操做:致使请求进程阻塞,直到I/O操做完成;

  • 异步I/O操做:不致使请求进程阻塞。

好,下面我用个人语言来总结一下阻塞,非阻塞,同步,异步

  • 阻塞,非阻塞:进程/线程要访问的数据是否就绪,进程/线程是否须要等待;

  • 同步,异步:访问数据的方式,同步须要主动读写数据,在读写数据的过程当中仍是会阻塞;异步只须要I/O操做完成的通知,并不主动读写数据,由操做系统内核完成数据的读写。

说3:解释的例子不一样

 

老张爱喝茶,废话不说,煮开水。
出场人物:老张,水壶两把(普通水壶,简称水壶;会响的水壶,简称响水壶)。
1 老张把水壶放到火上,立等水开。(同步阻塞)
老张以为本身有点傻
2 老张把水壶放到火上,去客厅看电视,时不时去厨房看看水开没有。(同步非阻塞)
老张仍是以为本身有点傻,因而变高端了,买了把会响笛的那种水壶。水开以后,能大声发出嘀~~~~的噪音。
3 老张把响水壶放到火上,立等水开。(异步阻塞)
老张以为这样傻等意义不大
4 老张把响水壶放到火上,去客厅看电视,水壶响以前再也不去看它了,响了再去拿壶。(异步非阻塞)
老张以为本身聪明了。


所谓同步异步,只是对于水壶而言。
普通水壶,同步;响水壶,异步。
虽然都能干活,但响水壶能够在本身完工以后,提示老张水开了。这是普通水壶所不能及的。
同步只能让调用者去轮询本身(状况2中),形成老张效率的低下。

所谓阻塞非阻塞,仅仅对于老张而言。
立等的老张,阻塞;看电视的老张,非阻塞。
状况1和状况3中老张就是阻塞的,媳妇喊他都不知道。虽然3中响水壶是异步的,可对于立等的老张没有太大的意义。因此通常异步是配合非阻塞使用的,这样才能发挥异步的效用。

——来源网络,做者不明。



说4:

做者:Shihui wang
连接:https://www.zhihu.com/question/19732473/answer/14413599
来源:知乎
著做权归做者全部。商业转载请联系做者得到受权,非商业转载请注明出处。
 

其余楼层包括从技术角度都有了详细解释。这里主要是针对其余网友的疑问作的补充和修改,考虑到须要在编程概念上更严谨一点。

  1. 阻塞非阻塞表示下面 买书过程当中 可能出现的状态,是从 这个单进程角度来看待这个买书这个问题。
  2. 同步异步表示一种协做方式,是从全局更高的角度 “进程之间 合做的方式” 来看待买书这个业务。两个进程之间若是商量采用异步方式处理买书这一业务,就不存在阻塞这种状态。

=============



A.概念

阻塞非阻塞: 请求不能当即获得应答,须要等待,那就是阻塞;不然能够理解为非阻塞。

同步异步: 某业务须要甲乙甚至多方合做的时候,

  1. 老是按照“甲方请求一次,乙方应答一次”这样的有序序列处理业务,只有当“一次请求一次应答”的过程结束才能够发生下一次的“一次请求一次应答”,那么就说他们采用的是同步。(同步IO中对同一个描述符的操做必须是有序的
  2. 若是甲方只要有须要,就会发送请求,无论上次请求有没有获得乙方应答。而乙方只要甲方有请求就会接受,不是等此次请求处理完毕再接受甲方新请求。这样请求应答分开的序列,就能够认为是异步。异步状况下,请求和应答不须要一致进行,可能甲方后请求的业务,却先获得乙方的应答。同步是线性的,而异步能够认为是并发的。(异步IO中,异步IO能够容许多方同时对同一个描述符发送IO请求,或者一次发多个请求,固然有机制保证如何区分这些请求,

举个例子:

  1. 我去买一本书,当即买到了,或者没有就走了,这就是非阻塞;(编程中设置IO成非阻塞,返回后再去检查描述符,或者等待通知,而后再去读取。至关于老板告诉我能够先忙点别的,过一会再来问问,或者老板通知我。但期间这个窗口(文件描述符)别人是用不了的)("当即买到了"在IO中也须要等待,不能算非阻塞IO)
  2. 若是刚好书店没有,我就等一直等到书店有了这本书买到了才走,这就是阻塞;而排在我后面的人呢只有我买到了书后才能再买书了。
  3. 若是书店刚好没有,我就告诉书店老板,书来了告诉我一声让我来取或者直接送到我家,而后我就走了,去作别的事了,这就是异步。这时候若是不少人来买书,都是老板登记一下完事。 (从IO角度来讲,“告诉我来取”,这个近似于信号驱动IO,不能算异步IO。必须书送到我家才算是异步,若是不送到我家,我想看这本书以前,终究仍是须要我跑一趟)
  4. 前面两种状况,非阻塞和阻塞均可以称为同步。

反映在编程方面就是 用户进程 调用 系统调用。(用户进程对应我,内核 对应 书店老板,书对应数据资源data , 买书就是一个系统调用了,其中内核拷贝数据到进程这个过程近似于老板送书到我手中)。


B. 在同步异步IO概念中,

同步异步的不一样在于,针对同一个描述符上的IO操做,从IO操做发起 获得 IO结果 这个过程而言,老是按照“发起请求,获得结果”这个有序序列进行的,这样便有了最小的等待这种状况:读取时,确知IO有数据,但须要等待内核拷贝数据到进程空间。这个最小状况的等待,同步IO都有。

 

unix网络编程中将IO模型分为5类:阻塞IO,非阻塞IO,IO复用,信号驱动,异步IO。

  1. 阻塞IO就是那种recv, read,一直等,等到有了数据才返回;
  2. 非阻塞IO就是当即返回,设置描述符为非阻塞,可是要进程本身一直检查是否可读;
  3. IO复用其实也是阻塞的,不过能够用来等不少描述符,比起阻塞有了进步,能够算有点异步了,但须要阻塞着检查是否可读。对同一个描述符的IO操做也是有序的。
  4. 信号驱动采用信号机制等待,有了更多的进步,不用监视描述符了,并且不用阻塞着等待数据到来,被动等待信号通知,由信号处理程序处理。但对同一个描述符的IO操做仍是有序的。
  5. 异步IO,发送IO请求后,不用等了,也再也不须要发送IO请求获取结果了。等到通知后,实际上是系统帮你把数据读取好了的,你等到的通知也再也不是要求你去读写IO了,而是告诉你IO请求过程已经结束了。你要作的就是能够处理数据了。且同一个描述符上可能同时存在不少请求。(对应上面那个买书例子中,就是送书到我家,我直接看书就好了,不须要再去跑一趟了)。

其中IO服用和信号驱动,在处理业务逻辑上能够说有异步,但在IO操做层面上来讲仍是同步的
 

posix.1严格定义的异步IO是要求没有任何一点阻塞,而上述的前面四个(阻塞IO,非阻塞IO,IO复用,信号驱动)都不一样程度阻塞了,并且都有一个共同的阻塞: 内核拷贝数据到进程空间的这段时间须要等待。 (因此上面的举例中: 必需要书送到我家,不然都不算异步,纠结。。。)

 

说5:

看看steven大叔的这篇文章。http://english.tebyan.net/newindex.aspx?pid=31159&BookID=23760&PageIndex=92&Language=3
同步和异步仅仅是关于所关注的消息如何通知的机制。同步的状况下,是由处理消息者本身去等待消息是否被触发,而异步的状况下是由触发机制来通知处理消息者
阻塞和非阻塞应该是发生在消息的处理的时刻。阻塞其实就是等待,发出通知,等待结果完成。非阻塞属于发出通知,当即返回结果,没有等待过程。



说6:不一样场景,银行业务的例子

来源:http://blog.chinaunix.net/uid-26000296-id-3754118.html

1、同步与异步
同步/异步, 它们是消息的通知机制

1. 概念解释
A. 同步
所谓同步,就是在发出一个功能调用时,在没有获得结果以前,该调用就不返回。

按照这个定义,其实绝大多数函数都是同步调用(例如sin isdigit等)。
可是通常而言,咱们在说同步、异步的时候,特指那些须要其余部件协做或者须要必定时间完成的任务。
最多见的例子就是 SendMessage。
该函数发送一个消息给某个窗口,在对方处理完消息以前,这个函数不返回。
当对方处理完毕之后,该函数才把消息处理函数所返回的值返回给调用者。


B. 异步
异步的概念和同步相对。
当一个异步过程调用发出后,调用者不会马上获得结果。
实际处理这个调用的部件是在调用发出后,
经过状态、通知来通知调用者,或经过回调函数处理这个调用。

以 Socket为例,
当一个客户端经过调用 Connect函数发出一个链接请求后,调用者线程不用等待结果,可马上继续向下运行。
当链接真正创建起来之后,socket底层会发送一个消息通知该对象。

C. 三种返回结果途径 
执行部件和调用者能够经过三种途径返回结果:
a.   状态、
b.   通知、
c.   回调函数。

可使用哪种依赖于执行部件的实现,除非执行部件提供多种选择,不然不受调用者控制。

a. 若是执行部件用状态来通知,
    那么调用者就须要每隔必定时间检查一次,效率就很低
    有些初学多线程编程的人,总喜欢用一个循环去检查某个变量的值,这实际上是一种很严重的错误。

b. 若是是使用通知的方式,
    效率则很高,由于执行部件几乎不须要作额外的操做。

c. 至于回调函数,
    和通知没太多区别。


2. 举例说明
理解这两个概念,能够用去银行办理业务(能够取钱,也能够存钱)来比喻:
当到银行后,
.能够去ATM机前排队等候                                -- (排队等候)就是同步等待消息
.能够去大厅拿号,等到排到个人号时,
 柜台的人会通知我轮到我去办理业务.              -- (等待别人通知)就是异步等待消息.

在异步消息通知机制中,
等待消息者(在这个例子中就是等待办理业务的人)每每注册一个回调机制,
在所等待的事件被触发时由触发机制(在这里是柜台的人)经过某种机制(在这里是写在小纸条上的号码)
找到等待该事件的人.

在select/poll 等IO 多路复用机制中就是fd,
当消息被触发时,触发机制经过fd 找处处理该fd的处理函数.

3. 在实际的程序中,
同步消息通知机制:就比如简单的read/write 操做,它们须要等待这两个操做成功才能返回;
                  同步, 是由处理消息者本身去等待消息是否被触发;
异步消息通知机制:相似于select/poll 之类的多路复用IO 操做,
                  当所关注的消息被触发时,由消息触发机制通知触发对消息的处理.
                  异步, 由触发机制来通知处理消息者;


仍是回到上面的例子,
轮到你办理业务, 这个就是你关注的消息,
而办理什么业务, 就是对这个消息的处理,
二者是有区别的.

而在真实的IO 操做时: 所关注的消息就是     该fd是否可读写,
                     而对消息的处理是     对这个fd 进行读写.

同步/异步仅仅关注的是如何通知消息,它们对如何处理消息并不关心,
比如说,银行的人仅仅通知你轮到你办理业务了,
而办理业务什么业务(存钱仍是取钱)他们是不知道的.

2、阻塞与非阻塞
阻塞/非阻塞, 它们是程序在等待消息(无所谓同步或者异步)时的状态.

1. 概念解释
A. 阻塞
阻塞调用是指调用结果返回以前,当前线程会被挂起。函数只有在获得结果以后才会返回。
有人也许会把阻塞调用和同步调用等同起来,实际上他是不一样的。
对于同步调用来讲,不少时候当前线程仍是激活的,只是从逻辑上当前函数没有返回而已。

socket接收数据函数recv是一个阻塞调用的例子。
当socket工做在阻塞模式的时候, 若是没有数据的状况下调用该函数,则当前线程就会被挂起,直到有数据为止。

B. 非阻塞
非阻塞和阻塞的概念相对应,指在不能马上获得结果以前,该函数不会阻塞当前线程,而会马上返回。

C. 对象的阻塞模式和阻塞函数调用
对象是否处于阻塞模式和函数是否是阻塞调用有很强的相关性,可是并非一一对应的。


阻塞对象上能够有非阻塞的调用方式,咱们能够经过必定的API去轮询状态,
在适当的时候调用阻塞函数,就能够避免阻塞。
而对于非阻塞对象,调用特殊的函数也能够进入阻塞调用。函数select就是这样的一个例子。

2. 举例说明
继续上面的那个例子,
不管是排队等待,仍是使用号码等待通知,
若是在这个等待的过程当中,
. 等待者除了等待消息以外不能作其它的事情,那么该机制就是阻塞的,
  表如今程序中,也就是该程序一直阻塞在该函数调用处不能继续往下执行.
. 相反,有的人喜欢在银行办理这些业务的时候一边打打电话发发短信一边等待,这样的状态就是非阻塞的,
  由于他(等待者)没有阻塞在这个消息通知上,而是一边作本身的事情一边等待.

3、易混淆的点
不少人也会把异步和非阻塞混淆,
由于异步操做通常都不会在真正的IO 操做处被阻塞,
好比若是用select 函数,当select 返回可读时再去read 通常都不会被阻塞
就比如当你的号码排到时通常都是在你以前已经没有人了,因此你再去柜台办理业务就不会被阻塞.
可见,同步/异步与阻塞/非阻塞是两组不一样的概念,它们能够共存组合,

而不少人之因此把同步和阻塞混淆,我想也是由于没有区分这两个概念,
好比阻塞的read/write 操做中,实际上是把消息通知和处理消息结合在了一块儿,
在这里所关注的消息就是fd 是否可读/写,而处理消息则是对fd 读/写.
当咱们将这个fd 设置为非阻塞的时候,read/write 操做就不会在等待消息通知这里阻塞,
若是fd 不可读/写则操做当即返回.


4、同步/异步与阻塞/非阻塞的组合分析
_______阻塞____________________非阻塞_____
同步 | 同步阻塞              同步非阻塞
异步 | 异步阻塞              异步非阻塞

同步阻塞形式:
  效率是最低的,
  拿上面的例子来讲,就是你专心排队,什么别的事都不作。

  实际程序中
  就是未对fd 设置O_NONBLOCK 标志位的read/write 操做,

异步阻塞形式:
  若是在银行等待办理业务的人采用的是异步的方式去等待消息被触发,也就是领了一张小纸条,
  假如在这段时间里他不能离开银行作其它的事情,那么很显然,这我的被阻塞在了这个等待的操做上面;


  异步操做是能够被阻塞住的,只不过它不是在处理消息时阻塞,而是在等待消息被触发时被阻塞.
  好比select 函数,
  假如传入的最后一个timeout 参数为NULL,那么若是所关注的事件没有一个被触发,
  程序就会一直阻塞在这个select 调用处.

同步非阻塞形式:
  其实是效率低下的,
  想象一下你一边打着电话一边还须要抬头看到底队伍排到你了没有,
  若是把打电话和观察排队的位置当作是程序的两个操做的话,
  这个程序须要在这两种不一样的行为之间来回的切换,效率可想而知是低下的;

  不少人会写阻塞的read/write 操做,
  可是别忘了能够对fd 设置O_NONBLOCK 标志位,这样就能够将同步操做变成非阻塞的了;

异步非阻塞形式:
  效率更高,
  由于打电话是你(等待者)的事情,而通知你则是柜台(消息触发机制)的事情,
  程序没有在两种不一样的操做中来回切换.

  好比说,这我的忽然发觉本身烟瘾犯了,须要出去抽根烟,
  因而他告诉大堂经理说,排到我这个号码的时候麻烦到外面通知我一下(注册一个回调函数),
  那么他就没有被阻塞在这个等待的操做上面,天然这个就是异步+非阻塞的方式了.

  若是使用异步非阻塞的状况,
  好比aio_*组的操做,当发起一个aio_read 操做时,函数会立刻返回不会被阻塞,
  当所关注的事件被触发时会调用以前注册的回调函数进行处理,

 文章摘抄的有点多,可是集思广益,各路看客能够对号入座,综合分析。采用什么方式,只有适合本身的业务处理需求才行。

相关文章
相关标签/搜索