BIO, NIO, AIO 的区别

本文详细介绍了三种不同的I/O模型:BIO、NIO和AIO。BIO是同步阻塞,每个连接对应一个线程。NIO基于Reactor模式,使用多路复用器实现一个线程处理多个连接。AIO则是异步非阻塞,读写操作完成后通过回调函数通知。同步I/O和异步I/O的区别在于数据读写阶段是否阻塞线程。理解这些概念有助于优化并发处理和系统性能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

BIO(Blocking I/O):

同步并阻塞,线程发起IO请求,不管内核是否准备好IO操作,从发起请求起,线程一直阻塞,直到操作完成。服务器实现模式为一个连接一个线程,即客户端有连接请求时服务器端就需要启动一个线程进行处理,如果这个连接不做任何事情会造成不必要的线程开销。

 

NIO(New I/O):

NIO基于Reactor,当socket有流可读或可写入socket时,操作系统会相应的通知应用程序进行处理,应用再将流读取到缓冲区或写入操作系统。  也就是说,这个时候,已经不是一个连接就要对应一个处理线程了,而是有效的请求,对应一个线程,当连接没有数据时,是没有工作线程来处理的。NIO的最重要的地方是当一个连接创建后,不需要对应一个线程,这个连接会被注册到多路复用器(selectpollepoll)上面,所以所有的连接只需要一个线程就可以搞定,当这个线程中的多路复用器进行轮询的时候,发现连接上有请求的话,才开启一个线程进行处理,也就是一个请求一个线程模式。

 ​​​​​​​​​​​​​​

AIO(Asynchronous I/O):

与NIO不同,当进行读写操作时,只须直接调用API的read或write方法即可。这两种方法均为异步的,对于读操作而言,当有流可读取时,操作系统会将可读的流传入read方法的缓冲区,并通知应用程序;对于写操作而言,当操作系统将write方法传递的流写入完毕时,操作系统主动通知应用程序。  即可以理解为,read/write方法都是异步的,完成后会主动调用回调函数。异步 IO 是基于事件和回调机制实现的,也就是应用操作之后会直接返回,不会堵塞在那里,当后台处理完成,操作系统会通知相应的线程进行后续的操作。

 

 

阻塞:当试图对该文件描述符进行读写时, 如果当时没有东西可读,或者暂时不可写, 程序就进入等待/挂起状态, 直到有东西可读或者可写为止(强迫症,必须这件事做完才能做其他事情,否则一直等待)

非阻塞: 如果没有东西可读, 或者不可写, 读写函数马上返回, 而不会等待/挂起(先取号,可以去做其他事情,叫号后,过来完成该事情)

同步I/O(触发I/O操作后,进行真正的I/O操作时)导致请求进程阻塞,直到I/O操作完成(该说法为POSIX标准定义,个人感觉有一点点问题,这把同步和阻塞挂钩了);获取I/O完成的方式,同步需要时刻主动关心I/O是否完成。同步就是发起一个调用后,被调用者未处理完请求之前,调用不返回。

异步I/O(触发I/O操作后,进行真正的I/O操作时)不导致请求进程阻塞(该说法为POSIX标准定义,个人感觉有一点点问题,这把异步和非阻塞挂钩了);异步无需主动关心I/O是否完成,在I/O完成后会收到通知。异步就是发起一个调用后,立刻得到被调用者的回应表示已接收到请求,但是被调用者并没有返回结果,此时我们可以处理其他的请求,被调用者通常依靠事件,回调等机制来通知调用者其返回结果。

 

如果按照POSIX的定义:

I/O操作分为两部分,发起I/O请求,和I/O数据读写。阻塞、非阻塞主要是针对线程发起I/O请求后,是否立即返回来定义的,立即返回称为非阻塞I/O,否则称为阻塞I/O。

同步、异步主要针对I/O数据读写来定义的,读写数据过程中不阻塞线程称为异步I/O,否则,称为同步I/O。

AIO 是帮助你从内核中将数据复制到用户空间中,并调用你传入的回调方法。 

NIO 是需要程序自己从内核中将数据复制到用户空间中,并需要程序自己调用相应的处理逻辑。

个人的理解是同步/异步主要针对被调用者的返回机制,而阻塞/非阻塞主要针对调用者的状态,二者很容易混淆,可以不必过分纠结,只需要弄清BIO、NIO和AIO的原理和区别即可。 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值