爱悠闲 > 基本概念:同步、异步、阻塞和非阻塞

基本概念:同步、异步、阻塞和非阻塞

分类: linux-C  |  标签: asynchronous,sockets,socket,library,include,多线程  |  作者: taolinke 相关  |  发布日期 : 2014-12-01  |  热度 : 139°

Asynchronous != Non-Blocking

     Since you are just learning this, I will assume that up till now you have been using blocking sockets. With that in mind, I will assume that you may have toyed around with non-blocking sockets. What is the difference?A socket that is blocked sends out a call and then waits for an answer. A non-blocking socket sends out a call and the program execution continues. This is exactly what asynchronous sockets do. However, there is a major difference.

      When using non-blocking sockets, you have to continually poll the socket to see whether or not you have any actions that need to be performed. These actions can include sending and receiving data, establishing a connection, sending back a response to a connection request, etc. Non-blocking sockets have the advantage in that they allow normal program execution to continue �  meaning you can process data while waiting for more to come in. This immediately makes them superior to blocking sockets in many cases (but not all).

      However, asynchronous sockets take polling to a new level � they do it for you. This means that you can focus on other things while WinSock keeps watch over your sockets. (Sounds better than non-blocking sockets eh? Not always, as you‘ll soon see.) So how does it do this? Well, um � I kinda like don’t really know, sorry. I do know it calls a library and that creates a thread or something and, and � well I can tell you how you are notified, even if I can‘t tell you how it knows to notify you. J Had ya going there, didn’t I?

同步

所谓同步,就是在发出一个功能调用时,在没有得到结果之前,该调用就不返回。按照这个定义,其实绝大多数函数都是同步调用(例如sin, isdigit等)。但是一般而言,我们在说同步、异步的时候,特指那些需要其他部件协作或者需要一定时间完成的任务。最常见的例子就是SendMessage。该函数发送一个消息给某个窗口,在对方处理完消息之前,这个函数不返回。当对方处理完毕以后,该函数才把消息处理函数所返回的LRESULT值返回给调用者。

异步

异步的概念和同步相对。当一个异步过程调用发出后,调用者不能立刻得到结果。实际处理这个调用的部件在完成后,通过状态、通知和回调来通知调用者。以CAsycSocket类为例(注意,CSocket从CAsyncSocket派生,但是起功能已经由异步转化为同步),当一个客户端通过调用Connect函数发出一个连接请求后,调用者线程立刻可以朝下运行。当连接真正建立起来以后,socket底层会发送一个消息通知该对象。
这里提到执行部件和调用者通过三种途径返回结果:状态、通知和回调。可以使用哪一种依赖于执行部件的实现,除非执行部件提供多种选择,否则不受调用者控制。如果执行部件用状态来通知,那么调用者就需要每隔一定时间检查一次,效率就很低(有些初学多线程编程的人,总喜欢用一个循环去检查某个变量的值,这其实是一种很严重的错误)。如果是使用通知的方式,效率则很高,因为执行部件几乎不需要做额外的操作。至于回调函数,其实和通知没太多区别。

阻塞

阻塞调用是指调用结果返回之前,当前线程会被挂起。函数只有在得到结果之后才会返回。
有人也许会把阻塞调用和同步调用等同起来,实际上他是不同的。对于同步调用来说,很多时候当前线程还是激活的,只是从逻辑上当前函数没有返回而已。例如,我们在CSocket中调用Receive函数,如果缓冲区中没有数据,这个函数就会一直等待,直到有数据才返回。而此时,当前线程还会继续处理各种各样的消息。如果主窗口和调用函数在同一个线程中,除非你在特殊的界面操作函数中调用,其实主界面还是应该可以刷新。
socket接收数据的另外一个函数recv则是一个阻塞调用的例子。当socket工作在阻塞模式的时候,如果没有数据的情况下调用该函数,则当前线程就会被挂起,直到有数据为止。

非阻塞

非阻塞和阻塞的概念相对应,指在不能立刻得到结果之前,该函数不会阻塞当前线程,而会立刻返回。