前言补充
阻塞与非阻塞
-
同步阻塞IO (Blocking IO) : 传统IO模型
-
同步非阻塞IO (Non-blocking IO): 默认创建的socket都是阻塞的,若是要设置成非阻塞IO需要socket被设置成NONBLOCK。
-
IO多路复用(IO Multiplexing): 经典的Reactor设计模式,有时也称为异步阻塞IO,Java中的Selector和Linux中的epoll都是这种模型
-
异步IO (Asynchronous IO): 经典的Proactor设计模式,也称为异步非阻塞IO
阻塞与非阻塞IO
对于操作系统内核而言,发生在等待资源阶段,根据发起IO请求是否阻塞来判断
阻塞IO
这种模式下下一个用户进程在发起一个IO操作之后,CPU只有在收到响应或者超时后才可以处理其他事情,否则IO将会一直阻塞,例如读取磁盘上一段文件,系统内核在完成磁盘寻道、读取数据、复制数据到内存之中,这个调用才算完成,阻塞的这段时间对CPU资源来说是浪费掉了。
非阻塞IO
这种模式下一个用户进程发起一个IO操作后,如果数据没有就绪,则会立刻返回,同时标记数据资源不可用,此时CPU时间片可以做其他的事情
同步与异步IO
发生在使用资源阶段,根据实际IO操作来判断
同步IO
应用发送或者接收数据后,如果不返回,那么就阻塞等待,直到数据成功或者失败返回
异步IO
应用发送或者接收数据后立刻返回,数据写入OS缓存,由OS完成数据发送或者接收,等OS处理完成发送或接受后再通知应用,通常是通过回调的方式,Node.js就是典型的异步编程的例子
无论是BIO,NIO(同步非阻塞)还是多路复用,都是同步IO模型,其中BIO是同步阻塞模型,NIO和多路复用是同步非阻塞模型。
多路IO复用
多路IO复用是一种同步IO模型,实现一个线程可以监视多个文件句柄;一旦某个文件句柄就绪,就能够通知应用程序执行相应的读写操作,没有文件句柄就绪时监视线程会被阻塞,交出CPU,直到有文件/连接就绪。多路指的是网络连接,复用指的是同一个线程可以被复用来服务多个文件描述符
常见的IO多路复用模型有:select模型,poll模型,epoll模型
select模型
select函数的API
#include <