同步,异步,阻塞,非阻塞
同步,异步与阻塞,非阻塞,在一些场景下,它们是同一个概念的不同名字;在另一些场景下,它们是不同的概念。
同一个概念的不同名字:
描述任务的时候:
同步,串行,阻塞是同一概念
异步,并行,非阻塞是同一个概念
不同的概念:
处理I/O的时候,所有的套接字编程都是同步I/O,只有使用了特殊的API才是异步I/O。
一个套接字上的输入操作,通常分为两步:
第一步,等待数据从网络中到达,缓存到内核空间
第二步,把数据从内核空间,拷贝到进程空间
同步与异步的区别在于第二步,同步需要主动把数据从内核空间拷贝到进程空间;异步由操作系统内核完成数据的拷贝。
- 阻塞式I/O
标红的这部分过程就是阻塞,直到阻塞结束recvfrom才能返回。
- 非阻塞式I/O
进程把一个套接字设置成非阻塞是在通知内核,当所请求的I/O操作不能立即完成时,不要把进程投入睡眠,而是返回一个错误。可以看出recvfrom是立即返回的,但是需要调用方不停的轮询。
- 多路复用式I/O
虽然I/O多路复用的函数也是阻塞的,但是其与以上两种还是有不同的,I/O多路复用是阻塞在select,epoll这样的系统调用之上,而没有阻塞在真正的I/O系统调用如recvfrom之上。
- 异步I/O
虽然I/O多路复用的函数也是阻塞的,但是其与以上两种还是有不同的,I/O多路复用是阻塞在select,epoll这样的系统调用之上,而没有阻塞在真正的I/O系统调用如recvfrom之上。红线标记处说明在调用时就可以立马返回,等函数操作完成会通知我们。
阻塞,非阻塞,多路复用
阻塞:
数据没有准备好,一直等着,直到数据准备好,一个线程只能管理一个IO
非阻塞:
数据没有准备好,返回错误码,然后隔一段时间,过来看一下,直到数据准备好,一个线程可以管理多个IO
多路复用,select:
阻塞在select上,当某一个IO可以操作时,select返回。然后遍历所有IO,找到可以操作的IO,进行操作
多路复用,epoll:
阻塞在epoll上,当某一个IO可以操作时, epoll返回,返回值中记录哪个IO可以操作,拿到返回值,直接进行IO操作
参考链接:
1 http://yaocoder.blog.51cto.com/2668309/1308899
2 http://stackoverflow.com/questions/2625493/asynchronous-vs-non-blocking