Linux 的五种 IO 模型,分别是:阻塞 IO、非阻塞 IO、多路复用 IO、信号驱动 IO 以及异步 IO。其中阻塞 IO、非阻塞 IO、多路复用 IO、信号驱动 IO 都属于同步 IO。
同步 IO:应用程序主动向内核查询是否有可用数据,如果有自己负责把数据从内核 copy 到用户空间。
异步 IO:应用程序向内核发起读数据请求需要:(1)告诉内核数据存放位置(2)注册回调函数,当内核完成数据 copy 后调用回调通知应用程序取数据。
同步IO/异步IO最大区别:同步 IO 数据从内核空间到用户空间的 copy 动作是由应用程序自己完成。而异步 IO 则是注册回调函数并告知内核用户空间缓冲区存放地址,数据 copy 由内核完成。
一般很少用这个非阻塞模型,因为反复调用消耗 CPU。
IO 复用模型是 Linux 下用的最多的,也就是 JDK 中的 NIO。
特点:
select 和 epoll,对一个 socket 两次调用,两次返回,比阻塞 IO 并没有什么优越性,关键是能实现同时对多个 socket 进行处理。
当一个异步过程调用发出后,系统直接返回,调用者不能立刻得到结果。实际处理这个调用的部件在完成后,通过状态、通知和回调来通知调用者的输入输出操作。
除异步 IO 模型,前面四种 IO 模型第二阶段都是相同的,阻塞于 recefrom 调用。
五种 IO 的模型:阻塞 IO、非阻塞 IO、多路复用 IO、信号驱动 IO 和异步 IO;前四种都是同步 IO,在内核数据 copy 到用户空间时都是阻塞的。
阻塞 IO 和非阻塞 IO 的区别在于第一步,发起 IO 请求是否会被阻塞,如果会那就是传统的阻塞 IO,如果不会那就是非阻塞 IO。
同步 IO 和异步 IO 的区别就在于第二个步骤是否阻塞,如果实际的 IO 读写阻塞请求进程,那么就是同步 IO;如果不阻塞,而是操作系统帮你做完 IO 操作再将结果返回给你,那么就是异步 IO。