理解阻塞非阻塞与同步异步的区别

来源:互联网 发布:淘宝店铺开张宣传语 编辑:程序博客网 时间:2024/05/31 05:28

理解阻塞非阻塞与同步异步的区别


论坛看到有人问阻塞非阻塞与同步异步的区别,想想我也不是很清楚,说不出个所以然,所以就整理出了这篇博文。

1.同步和异步——消息通信机制(关注的仅仅是如何通知消息,而对于消息的处理并不关心)

同步,就是在调用者发起调用的时候,会一直等待调用结果;
举个通俗的例子:去餐厅吃饭的时候,人有点多,你点好了餐,然后就在那边等,等到厨师为你准备好了再找个位子吃饭。
异步,就是在调用者发起调用之后就返回了,没有返回结果,(意思就是在一个异步调用发起之后,调用者不会立刻得到结果)而是在被调用者通过状态、通知、来通知调用者,或是通过回调函数处理这个调用。
举个通俗的例子如上:在你点好餐后拿到一个小排号,然后你就去干你的事情了,等待服务员的大喇叭叫你。

简单概括就是:在最后获取数据的这个对话,是哪边发起的,对于应用而言,主动就是同步,被动就是异步。

2.阻塞与非阻塞

阻塞与非阻塞,就是在上面的通信机制中,IO请求发起到获得数据这段时间,应用是在等还是不等。用专业的话讲就是:阻塞与非阻塞与是否是同步/异步无关,与程序等待消息时的状态有关。

同步中的阻塞与非阻塞

阻塞就是应用等待不干活。就像上面的案例一样你在等厨师把你的饭做完。但是呢对于操作系统而言,阻塞并不是坏事。操作系统的功能之一就是系统资源的调度,当某个线程阻塞了,它就能调度CPU资源给别的进程。这其实提高了不少效率。
非阻塞,就是应用不断轮询,直到拿到数据。就上面的案例而言就是你在等餐的时候,你可以干别的事情,比如打电话,但是呢你必须时不时的抬头看看有没有到你了。非阻塞相比于阻塞会浪费一些CPU,所以性能会差一些。

异步中的阻塞与非阻塞

很多人又会问了,异步操作不会是阻塞的吧?已经通知了有消息可以处理了就一定不是阻塞的了吧?
其实异步操作是可以被阻塞住的,只不过通常不是在处理消息时阻塞,而是在等待消息被触发时被阻塞.比如select函数,假如传入的最后一个timeout参数为NULL,那么如果所关注的事件没有一个被触发,程序就会一直阻塞在这个select调用处.而如果使用异步非阻塞的情况,比如aio组的操作,当我发起一个aio_read操作时,函数会马上返回不会被阻塞,当所关注的事件被触发时会调用之前注册的回调函数进行处理。

最后总结一下:

阻塞,非阻塞:
阻塞和非阻塞关注的是程序在等待调用结果(消息,返回值)是的状态。
(进程/线程要访问的数据是否就绪,进程/线程是否需要等待)

同步,异步:
同步和异步关注的是消息通信机制;
(访问数据的方式,同步需要主动读写数据,在读写数据的过程中还是会阻塞;异步只需要IO操作完成的通知,并不主动读写数据,由操作系统内核完成数据的读写)

阻塞其实就是把调度的权力给了操作系统,让操作系统来提高利系统用率。非阻塞则是把这个权力给了开发者,因为不阻塞的话我们可以做些别的事情,类似于程序内部的一个调度功能。

参考文献:
http://www.cppblog.com/converse/archive/2009/05/13/82879.aspx
http://www.kryptosx.info/archives/1388.html
http://yaocoder.blog.51cto.com/2668309/1308899
精简概述

0 0
原创粉丝点击