同步/异步、阻塞/非阻塞

时间:2022-09-09 21:13:47

同步/异步、阻塞/非阻塞的区别,是个仁者见仁智者见智的话题。

同步与异步的理解

同步与异步的重点在消息通知的方式上,也就是调用结果通知的方式。
同步:当一个同步调用发出去后,调用者要一直等待调用结果的通知后,才能进行后续的执行。
异步:当一个异步调用发出去后,调用者不能立即得到调用结果的返回。
异步调用,要想获得结果,一般有两种方式:
1、主动轮询异步调用的结果;
2、被调用方通过callback来通知调用方调用结果。

阻塞与非阻塞的理解

阻塞与非阻塞的重点在于进/线程等待消息时候的行为,也就是在等待消息的时候,当前进/线程是挂起状态,还是非挂起状态。
1、阻塞阻塞调用在发出去后,在消息返回之前,当前进/线程会被挂起,直到有消息返回,当前进/线程才会被激活
2、 非阻塞非阻塞调用在发出去后,不会阻塞当前进/线程,而会立即返回。

Richard Stevens的“UNIX® Network Programming Volume 1, Third Edition: The Sockets Networking ”在文章中一共比较了五种IO Model:

1 blocking IO
2 nonblocking IO
3 IO multiplexing
4 signal driven IO
5 asynchronous IO

blocking和non-blocking的区别:

调用blocking IO会一直block住对应的进程直到操作完成,而non-blocking IO在kernel还准备数据的情况下会立刻返回。

synchronous IO和asynchronous IO的区别:

Stevens给出的定义(其实是POSIX的定义)是这样子的:
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;
两者的区别就在于synchronous IO做”IO operation”的时候会将process阻塞。按照这个定义,之前所述的blocking IO,non-blocking IO,IO multiplexing都属于synchronous IO。有人可能会说,non-blocking IO并没有被block啊。这里有个非常“狡猾”的地方,定义中所指的”IO operation”是指真实的IO操作,就是例子中的recvfrom这个system call。non-blocking IO在执行recvfrom这个system call的时候,如果kernel的数据没有准备好,这时候不会block进程。但是,当kernel中数据准备好的时候,recvfrom会将数据从kernel拷贝到用户内存中,这个时候进程是被block了,在这段时间内,进程是被block的。而asynchronous IO则不一样,当进程发起IO 操作之后,就直接返回再也不理睬了,直到kernel发送一个信号,告诉进程说IO完成。在这整个过程中,进程完全没有被block。

所以,作者在文章中指明了异步IO(asynchronous IO)就是异步IO,与阻塞非阻塞没有关系,或者说,在asynchronous IO操作中不存在阻塞的问题,阻塞只可能发生在上层调用者。同步/异步、阻塞/非阻塞的层次在根本上就是不一样的。

详细可参考以下网址
参考网址:

https://www.zhihu.com/question/19732473
https://www.zhihu.com/question/27965282
http://www.smithfox.com/?e=191
https://zhuanlan.zhihu.com/p/21416728
http://blog.csdn.net/dinglang_2009/article/details/50461697
https://blog.csdn.net/historyasamirror/article/details/5778378
http://www.cnblogs.com/Anker/p/5965654.html