今天看到《WIN32多线程程序设计》的同步控制时,才发现原来自己对同步和异步的概念很模糊,甚至混淆。于是GOOGLE了一下。
下面都是高人们的见解,简单明了。
------------------------------------------------------------------------------------------------------
同步是指:发送方发出数据后,等接收方发回响应以后才发下一个数据包的通讯方式。
异步是指:发送方发出数据后,不等接收方发回响应,接着发送下个数据包的通讯方式。
举个不太恰当的例子,就像:
SendMessage(...)
TRACE0("just like send");
PostMessage(...)
TRACE0("just like WSASend using overlapped");
SendMessage是调用的时候不返回,等消息响应后才执行TRACE0,这就是同步.
PostMessage是调用后马上返回,不用消息响应就执行TRACE0,这就是异步.
答案三:
同步和异步的区别
举个例子:普通B/S模式(同步)AJAX技术(异步)
同步:提交请求->等待服务器处理->处理完毕返回 这个期间客户端浏览器不能干任何事
异步: 请求通过事件触发->服务器处理(这是浏览器仍然可以作其他事情)->处理完毕
--------------------------------------------------------------------------------------------------------------------
同步就是你叫我去吃饭,我听到了就和你去吃饭;如果没有听到,你就不停的叫,直到我告诉你听到了,才一起去吃饭。
异步就是你叫我,然后自己去吃饭,我得到消息后可能立即走,也可能等到下班才去吃饭。
所以,要我请你吃饭就用同步的方法,要请我吃饭就用异步的方法,这样你可以省钱。
--------------------------------------------------------------------------------------------------------------------
举个例子 打电话时同步 发消息是异步
-------------------------------------------------------------
同步、异步、阻塞和非阻塞的概念
在进行网络编程时,我们常常见到同步、异步、阻塞和非阻塞四种调用方式。这些方式彼此概念并不好理解。下面是我对这些术语的理解。
同步
所 谓同步,就是在发出一个功能调用时,在没有得到结果之前,该调用就不返回。按照这个定义,其实绝大多数函数都是同步调用(例如sin, isdigit等)。但是一般而言,我们在说同步、异步的时候,特指那些需要其他部件协作或者需要一定时间完成的任务。最常见的例子就是 SendMessage。该函数发送一个消息给某个窗口,在对方处理完消息之前,这个函数不返回。当对方处理完毕以后,该函数才把消息处理函数所返回的 LRESULT值返回给调用者。
异步
异步的概念和同步相对。当一个异步过程调用发出后,调用者不能立刻得到结果。实际处理这个调用的部件 在完成后,通过状态、通知和回调来通知调用者。以CAsycSocket类为例(注意,CSocket从CAsyncSocket派生,但是起功能已经由 异步转化为同步),当一个客户端通过调用 Connect函数发出一个连接请求后,调用者线程立刻可以朝下运行。当连接真正建立起来以后,socket底层会发送一个消息通知该对象。这里提到执行 部件和调用者通过三种途径返回结果:状态、通知和回调。可以使用哪一种依赖于执行部件的实现,除非执行部件提供多种选择,否则不受调用者控制。如果执行部 件用状态来通知,那么调用者就需要每隔一定时间检查一次,效率就很低(有些初学多线程编程的人,总喜欢用一个循环去检查某个变量的值,这其实是一种很严重 的错误)。如果是使用通知的方式,效率则很高,因为执行部件几乎不需要做额外的操作。至于回调函数,其实和通知没太多区别。
阻塞
阻塞调用 是指调用结果返回之前,当前线程会被挂起。函数只有在得到结果之后才会返回。有人也许会把阻塞调用和同步调用等同起来,实际上他是不同的。对于同步调用来 说,很多时候当前线程还是激活的,只是从逻辑上当前函数没有返回而已。例如,我们在CSocket中调用Receive函数,如果缓冲区中没有数据,这个 函数就会一直等待,直到有数据才返回。而此时,当前线程还会继续处理各种各样的消息。如果主窗口和调用函数在同一个线程中,除非你在特殊的界面操作函数中 调用,其实主界面还是应该可以刷新。socket接收数据的另外一个函数recv则是一个阻塞调用的例子。当socket工作在阻塞模式的时候,如果没有 数据的情况下调用该函数,则当前线程就会被挂起,直到有数据为止。
非阻塞
非阻塞和阻塞的概念相对应,指在不能立刻得到结果之前,该函数不会阻塞当前线程,而会立刻返回。
对象的阻塞模式和阻塞函数调用
对 象是否处于阻塞模式和函数是不是阻塞调用有很强的相关性,但是并不是一一对应的。阻塞对象上可以有非阻塞的调用方式,我们可以通过一定的API去轮询状 态,在适当的时候调用阻塞函数,就可以避免阻塞。而对于非阻塞对象,调用特殊的函数也可以进入阻塞调用。函数select就是这样的一个例子
1.服务器端和客户端的服务请求的同步异步
- 同步:提交请求->等待服务器处理->处理完毕->返回 这个期间客户端不能干任何事
- 异步:请求通过事件触发->服务器处理(这时客户端仍然可以做其它事情)->处理完毕
- 例子:打电话是同步,发电报是异步
2.软件执行级别的同步异步
- 同步:可以理解为在执行完一个函数或方法之后,一直等待系统返回值或消息,这时程序是处于阻塞的,只有接收到返回的值或消息后才往下执行其它的命令。
- 异步,执行完函数或方法后,不必阻塞性地等待返回值或消息,只需要向系统委托一个异步过程,那么当系统接收到返回值或消息时,系统会自动触发委托的异步过程,从而完成一个完整的流程。
- 并不是说谁好谁不好,只是同步的机制不适合在正式应用的项目当中(但自己测试还是可以的)
- 异步通信”是一种很常用的通信方式。异步通信在发送字符时,所发送的字符之间的时间间隔可以是任意的。当然,接收端必须时刻做好接收的准备(如果接收端主机的电源都没有加上,那么发送端发送字符就没有意义,因为接收端根本无法接收)。发送端可以在任意时刻开始发送字符,因此必须在每一个字符的开始和结束的地方加上标志,即加上开始位和停止位,以便使接收端能够正确地将每一个字符接收下来。异步通信的好处是通信设备简单、便宜,但传输效率较低(因为开始位和停止位的开销所占比例较大)。
- 异步通信也可以是以帧作为发送的单位。接收端必须随时做好接收帧的准备。这是,帧的首部必须设有一些特殊的比特组合,使得接收端能够找出一帧的开始。这也称为帧定界。帧定界还包含确定帧的结束位置。这有两种方法。一种是在帧的尾部设有某种特殊的比特组合来标志帧的结束。或者在帧首部中设有帧长度的字段。需要注意的是,在异步发送帧时,并不是说发送端对帧中的每一个字符都必须加上开始位和停止位后再发送出去,而是说,发送端可以在任意时间发送一个帧,而帧与帧之间的时间间隔也可以是任意的。在一帧中的所有比特是连续发送的。发送端不需要在发送一帧之前和接收端进行协调(不需要先进行比特同步)。 每个字符开始发送的时间可以是任意的t0 0 1 1 0 1 1 0起始位结束位t每个帧开始发送的时间可以是任意的以字符为单位发送以帧为单位发送帧开始帧结束
- “同步通信”的通信双方必须先建立同步,即双方的时钟要调整到同一个频率。收发双方不停地发送和接收连续的同步比特流。但这时还有两种不同的同步方式。一种是使用全网同步,用一个非常精确的主时钟对全网所有结点上的时钟进行同步。另一种是使用准同步,各结点的时钟之间允许有微小的误差,然后采用其他措施实现同步传输。