阻塞IO模型
进程发起io系统调用后,进程被阻塞,由内核进行处理,整个io处理完毕后返回进程
特点
- 进程的挂起和阻塞不消耗cpu资源
- 开发简单
- 适合并发量小的应用开发
缺点
- 不适合并发量大的应用开发,因为需要为每个请求分配一个进程(线程)
非阻塞IO模型
进程发起io系统调用后,如果内核缓冲区没有数据,需要到io设备中读取,进程返回一个错误而不会被阻塞
进程发起io系统调用后,如果内核缓冲区有数据,内核就会把数据返回进程
当内核数据没准备好需要进程阻塞的时候,就返回一个错误,以使得进程不被阻塞
特点
- 进程不断轮询调用,消耗cpu资源
- 开发难度略高于阻塞IO模型
- 适用于并发量较小,且不需要即使响应的应用开发
IO复用模型
多个进程的io可以注册到一个复用器上,然后用一个进程调用该复用器,复用器会监听所有注册进来的io
如果复用器监听的io在内核缓冲区没有数据时,复用器黑被阻塞;而当在内核缓冲区中有数据时,复用器调用就会返回
而后复用器进程可以通知另外的注册进程再次发起读取io,读取内核中准备好的数据
特点
- 由一个进程解决多个进程io的阻塞问题,性能好
- 开发难度较大
- 适用于高并发开发
linux中io复用的主要方式有select、poll、epoll
- select:注册io、阻塞扫描、监听的io最大连接数不能多于FD_SIZE
- poll:原理和select相似,每一个数量限制,但io数量大扫描性能线性下降
- epoll:事件驱动不阻塞,mmap实现内核与用户空间的消息传递,数量很大,linux2.6后内核支持
信号驱动IO模型
当进程发起一个io操作,会向内核注册一个信号处理函数,然后进程返回不阻塞
当内核数据就绪时会发送一个信号给进程,进程便在信号处理函数中调用io读取数据
特点
- 回调机制
- 开发难度大
异步IO模型
当进程发起一个io操作,进程返回,但不返回结果,内核把整个io处理完后,会通知进程结果。如果io操作成功则直接获取到数据
特点
- 不阻塞,数据一步到位
- 需要操作系统底层支持
- 实现难度大
- 非常适合高性能高并发应用