一个IO操做涉及两个系统对象:html
一个具体的Read操做包括两个阶段:编程
只有在同步的状况下才会有“阻塞”和“非阻塞”之说,异步状况,必须是非阻塞的!网络
“同步 - 异步”指访问数据的一种协做方式,同步须要主动读写数据,在读写数据的过程当中仍是会阻塞;异步只须要I/O操做完成的通知,并不主动读写数据,由内核完成数据的读写。“阻塞 - 非阻塞”指进程/线程要访问的数据是否就绪,进程/线程是否须要等待。同步和异步着重点在于多个任务的执行过程当中,一个任务的执行是否会致使整个流程的暂时等待,阻塞和非阻塞着重点在于发出一个请求操做时,若是进行操做的条件不知足是否会返会一个标志信息告知条件不知足。多线程
同步/异步仅关注消息通知的方式,并不关心消息如何处理,消息处理过程当中应用程序(线程)的状态用阻塞/非阻塞来描述,是函数/方法的实现方式。并发
参考:socket阻塞与非阻塞、同步与异步概念详解 - 1;socket阻塞与非阻塞、同步与异步概念详解 - 2;异步
消息的通知机制,针对Client端(和Server端的交互),进程/线程触发IO操做后:socket
其中,异步中处理的执行部经过三种途径返回结果给调用者:函数
同步 Synchronousui
A Synchronous-I/O operation causes the requesting process to be blocked until that I/O operation completes.spa
串行,无条件等待,具体见下前4种I/O。
异步 Asynchronous
An Asynchronous-I/O operation does not cause the requesting process to be blocked.
并发,无需等待、无需轮询,具体见下异步I/O。
应用程序在等待消息时的状态,针对Server端,Server端是否阻塞与Client端无关,至于Client端在等待的前提下啥也不作仍是边作其余事边等待,由Client端本身决定。关于阻塞/非阻塞,在网络编程中一般应用在是否是须要等待数据就绪。
阻塞 Blocking
挂起等待,具体见下阻塞I/O。
非阻塞 Non-Blocking
轮询检查等待,具体见下非阻塞I/O。
阻塞I/O(Blocking I/O)
进程阻塞等待,进程挂起睡眠直到数据拷贝完成。
简单易实现,不适于同时处理大量套接字、扩展性差。改进:
非阻塞I/O(Non-Blocking I/O)
进程非阻塞等待,数据准备阶段进程不睡眠而是轮询等待(致使CPU占用率高)、数据拷贝阶段进程阻塞。
便于处理多套接字的通讯,但实现复杂、需仔细检查返回代码并对收到的错误信息进行处理。
I/O多路复用(I/O Multiplexing) Reactor模式
对一个IO端口,两次调用、两次返回。
数据准备阶段进程阻塞等待于select()/epoll()、数据拷贝阶段进程阻塞,其中select()能够同时阻塞多个I/O端口的操做,直到某个端口有数据可读/写时,才真正调用I/O操做函数。 实现同时对多个IO端口进行监听,适于处理大量套接字的链接。
I/O多路复用经典模式(2种):
参考:Reactor和Proactor;
信号驱动I/O(Signal Driven I/O)
两次调用,两次返回。
数据准备阶段进程继续执行、数据拷贝阶段进程阻塞。 须要创建信号处理程序。
异步I/O(Asynchronous I/O) Proactor模式
无阻塞,无需等待、无需轮询、无需多线程。
异步过程调用,调用者不能马上获得结果,实际处理这个调用的部件在完成处理后,经过状态、通知或回调来通知调用者。异步需操做系统的底层支持。
注:信号驱动模型由内核通知用户能够开始一个IO操做(数据在内核缓冲区中),异步IO由内核通知IO操做已经完成(数据已在用户空间中)。
比较
同步IO - 异步IO:数据访问时的消息通知机制,数据访问/拷贝时(第二阶段)进程是否等待,主动等待仍是被动通知等待消息的触发! 同步IO和异步IO的关键区别反映在数据拷贝阶段是由用户线程完成仍是内核完成。
阻塞IO - 非阻塞IO:等待数据就绪时(第一阶段)应用程序的调用是否当即返回!
推荐书籍:
参考: