一、这个技术出现的背景、初衷和要达到什么样的目标或是要解决什么样的问题
二、这个技术的优势和劣势分别是什么
三、这个技术适用的场景。任何技术都有其适用的场景,离开了这个场景
四、技术的组成部分和关键点。
五、技术的底层原理和关键实现
六、已有的实现和它之间的对比
Java 中的 BIO、NIO和 AIO 理解为是 Java 语言对操作系统的各种 IO 模型的封装。
程序员在使用这些 API 的时候,不需要关心操作系统层面的知识,也不需要根据不同操作系统编写不同的代码。只需要使用Java的API就可以了。厉害呀
‘’
5个
细节是魔鬼:
异步定义:An asynchronous IO operation does not cause the requesting process to be blocked.
aio 纯异步,io多路复用也是异步。wait for data 和copy data from kernel to user
同步定义:A synchronous IO operation causes the requesting process to be blocked until that IO operation completes.
1 BIO(Blocking IO) BIO是同步阻塞模型,一个客户端连接对应一个处理线程。在BIO中,accept和read方法都是阻塞操作,如果没有连接请求,accept方法阻塞;如果无数据可读取,read方法阻塞。
2 NIO(Non Blocking IO) NIO是同步非阻塞模型,服务端的一个线程可以处理多个请求,客户端发送的连接请求注册在多路复用器Selector上,服务端线程通过轮询多路复用器查看是否有IO请求,有则进行处理。
3 AIO(NIO 2.0) AIO是异步非阻塞模型,一般用于连接数较多且连接时间较长的应用,在读写事件完成后由回调服务去通知程序启动线程进行处理。
AIO 看上去和 Signal Driven IO 很相似,但区别在于 Signal Driver IO 是在数据可读后就通过 SIGIO 信号通知应用程序数据可读了,之后由应用程序来实际读取数据,拷贝数据到 User Space。而 AIO 是注册一个读任务后,直到读任务真的完全完成后才会通知应用层。
可以看出 Proactor 和 Reactor 的区别:
1)Reactor 是在事件发生时就通知事先注册的事件(读写在应用程序线程中处理完成);
2)Proactor 是在事件发生时基于异步 I/O 完成读写操作(由内核完成),待 I/O 操作完成后才回调应用程序的处理器来进行业务处理。
Reactor 可以理解为「来了事件操作系统通知应用进程,让应用进程来处理」, 而 Proactor 可以理解为「来了事件操作系统来处理,处理完再通知应用进程」
现在我们再来理解 Reactor 和 Proactor 的区别,就比较清晰了。
Reactor 是非阻塞同步网络模式,感知的是就绪可读写事件。在每次感知到有事件发生(比如可读就绪事件)后,就需要应用进程主动调用 read 方法来完成数据的读取,
也就是要应用进程主动将 socket 接收缓存中的数据读到应用进程内存中, 这个过程是同步的,读取完数据后应用进程才能处理数据。
Proactor 是异步网络模式, 感知的是已完成的读写事件。
在发起异步读写请求时,需要传入数据缓冲区的地址(用来存放结果数据)等信息,这样系统内核才可以自动帮我们把数据的读写工作完成, 这里的读写工作全程由操作系统来做,
并不需要像 Reactor 那样还需要应用进程主动发起 read/write 来读写数据, 操作系统完成读写工作后,就会通知应用进程直接处理数据。
单 Reactor 单进程的方案不适用计算机密集型的场景,只适用于业务处理非常快速的场景
而且只在主线程中运行,在面对瞬间高并发的场景时,容易成为性能的瓶颈的地方。
单 Reator 多线程的方案优势在于能够充分利用多核 CPU 的能,那既然引入多线程,那么自然就带来了多线程竞争资源的问题。
Acceptor 对象中的 accept 获取连接,将新的连接分配给某个子线程;
无论是 Reactor,还是 Proactor,都是一种基于「事件分发」的网络编程模式,区别在于 Reactor 模式是基于「待完成」的 I/O 事件,而 Proactor 模式则是基于「已完成」的 I/O 事件。
接下来,一起看看 Proactor 模式的示意图:
可惜的是,在 Linux 下的异步 I/O 是不完善的
Proactor is a software design pattern for event handling in which long running activities are running in an asynchronous part
细节是蘑菇:
定义:
kqueue 是一种可扩展的事件通知接口。
Kqueue is a scalable event notification interface introduced in FreeBSD 4.1 on July 2000
2000 年 7 月发布的 FreeBSD 4.1 中首次引入了 kqueue[1],
随后也被 NetBSD、OpenBSD、macOS 等操作系统支持。
Kqueue makes it possible for software like nginx to solve the c10k problem
epoll
在文件描述符可进行 I/O 操作时进行通知,Java NIO2增加了对第五种模型的支持,也就是AIO。http://hg.openjdk.java.net/nio/nio/jdk/file/a11b4063024f/src/share/classes/sun/nio/ch
https://www.boost.org/doc/libs/1_48_0/doc/html/boost_asio.html https://www.boost.org/doc/libs/1_48_0/doc/html/boost_asio/overview/core/basics.html 【完成】
https://colobu.com/2014/11/13/java-aio-introduction/ 【】
libevent supports /dev/poll, kqueue(2), event ports, POSIX select(2), Windows select(), poll(2), and epoll(4).
https://libevent-users.monkey.narkive.com/MXzHLDTN/aio-support https://sourceforge.net/p/levent/patches/13/
On FreeBSD notification via kqueue is supported, on other platforms default implementation with signal notification supposed to be used. https://oxnz.github.io/2016/10/13/linux-aio/
nonblocking I/O
I/O multiplexing (select and poll)
signal driven I/O (SIGIO)
asynchronous I/O (the POSIX aio_functions)
https://www.dre.vanderbilt.edu/~schmidt/PDF/proactor.pdf
https://en.wikipedia.org/wiki/Proactor_pattern
【翻译】两种高性能I/O设计模式(Reactor/Proactor)的比较
https://blog.csdn.net/liu251/article/details/8351197
Comparing Two High-Performance I/O Design Patterns
Read-Completed /Ready-to-Read
Standard/classic Reactor:
Proposed emulated Proactor:
优缺点:
— Decoupling threading from concurrency.
ー线程与并发性的分离。
Long-duration operations are performed asynchronously by the implementation on behalf of the application. Consequently applications do not need to spawn many threads in order to increase concurrency. 长时间的操作由代表应用程序的实现异步执行。因此,应用程序不需要产生许多线程来提高并发性。
— Performance and scalability.
high-performance concurrent applications
https://www.cnblogs.com/l
uminocean/p/5631336.html