首页 > 其他分享 >网络IO模型:BIO、NIO、AIO的区别

网络IO模型:BIO、NIO、AIO的区别

时间:2023-06-29 23:13:40浏览次数:57  
标签:BIO NIO 阻塞 AIO 线程 IO 缓冲区 数据 socket

1.BIO,即Blocking IO,同步阻塞IO,最原始的实现方式,每个socket在进行IO请求时(发送数据或接收数据)都会阻塞线程,所以有多少个IO请求就需要多少个线程;

这里同步和异步是一种逻辑概念,比如我调用某个接口是异步接口,即对方不会等处理完业务后告诉我业务处理结果,而是直接就返回了,需要我们后续通过其他方式来验证是否执行成功

,但是这个IO本身又是同步的,即socket也是要同步把数据发送到了对方,也要同步获取到了对方返回的接收到了我们的请求的响应才算请求完成,因此这个层面它又是同步的;

 

而阻塞个人理解应该是要和线程进行挂钩,即阻塞会导致线程sleep、或者自旋或者wait等情况;

 

阻塞是分为这几种:

阻塞式发送:发送方线程会被阻塞(阻塞就是线程在这段时间无法做其他事情,哪怕它获取到了时间片)

非阻塞式发送:发送方线程send后立刻返回,然后可以执行其他操作

阻塞式接收:接收方线程调用receive方法后一直阻塞,直到有可用消息到达;(UDP就是要完整的报文,而TCP则看情况可能是一个字节也可能是多个字节)

非阻塞式接收:调用receive方法后要么得到一个有效的数据,要么直接返回一个空值而不会等待一个有效数据,即不会被阻塞;

 

异步是callback的主动通知?

 

这里的概念其实也和具体实现有关,不同语言,不同系统的这几个概念也不是完全一样的。。

 

java里的NIO是同步非阻塞,这里的同步也是api的同步(逻辑概念),即我调用read方法是同步检测是否读取到了数据,但是它没有读取到也会立刻返回;

 

BIO最大的问题就是一个线程只能处理一个连接,即连接无论是发送还是接收或者连接服务都会阻塞当前线程(IO阻塞,非SLEEP或wait);

导致连接一多需要的线程也越多,然后线程切换带来资源消耗;

NIO则是解决了一个线程只能处理一个连接的问题,这里就涉及到非阻塞读和非阻塞写:

非阻塞读:即线程socket.read(buffer)会由用户态转变为内核态,去内核中查询socket接收缓冲区是否有数据,如果缓冲区有数据则立刻拷贝到buffer里(用户态;这个拷贝过程是阻塞的),并在返回值里告诉读取了多少数据;如果缓冲区没有数据,则会立刻返回而不会产生阻塞,也不会让出CPU,只是返回-1表示没有读取到数据;【所以非阻塞读涉及到 内核态缓冲区,用户态buffer,读取的数据量这些概念】

非阻塞写:阻塞写是用户态将buffer的数据写入到内核态缓冲区(写的缓冲区,读的是另外一个【读写缓冲区就是一根管道,有source、target】),必须得把buffer的所有数据都写完才会返回,所以它需要等待操作系统将该socket内核态写缓冲区的数据发送成功清理出缓冲空间,然后用户态的buffer能完全写入到缓冲区才结束;而非阻塞写则是不要求将用户态的buffer全部写完,而是可以写多少就写多少,写完立刻返回用户写成功了多少,然后由用户自己去写剩下的数据;

【而之所以BIO的socket的IO操作都会消耗一个线程就是因为它的IO操作方法的头铁行为(注意不是说BIO一个socket就一定会消耗一个线程,是完全可以创建N个socket保存到全局数组里不做任何操作,然后不阻塞任何线程的,这里说的都是指它的IO操作方法会导致占用线程,即阻塞线程);而我们现在有了非阻塞读和非阻塞写方法,那么socket的IO操作方法就不会因为没有完全成功(如没有完全写入数据成功或没有读取到任何数据)而阻塞线程;我们就可以通过一个线程来轮询检查多个socket的缓冲区是否有数据到达,比如发现socket a的读缓冲区有数据了/写缓冲区还有空间 则立刻返回数据或可写空间大小(当然没有数据或写缓冲空间也会立刻返回,只是返回告诉用户态没有数据或可写空间而已),在java里就是一个线程不断的执行select()方法,然后判断其是否可读,如果可读则得到可读的channel(就是服务端可以和多个客户端通信,每个通信都会产生一个channel,在同步阻塞里每个channel是单独进行BIO读写方法的,所以一个服务socket连接的客户端越多且都进行通信就会导致被阻塞的线程越多),然后用这个channel.read(buffer)来读取这个channel的读缓冲区里的数据到用户态;所以Java的NIO似乎只适合于服务端,客户端用处不大,因为它不存在多路复用,它自己就只会产生一根管道,除非一个NIO客户端可以连接多个服务端产生多个channel或者多个socketChannel对象可以共用一个selector检查这些channel的缓冲区(看了下还真的可以,先创建一个Selector对象,然后一个socketChannel.open和.connect服务a后,通过socketChannel.register(selector, XXOPER),然后又通过socketChannel2.open和.connect服务b后,再通过socketChannel2.register(selector, XXOPER)来实现一个selector监听同多个socketChannel对象的XX缓冲区】,NIO也有缺点,就是得有个单独的线程不断的select()检查多个channel(读/写/连接等的缓冲区),如果一直没有数据那反而成为累赘,CPU在空转。

 

AIO就是增加Future,当read的时候会直接返回Future<Integer>对象,通过future.get()来获取真正读取的值,但是这种方式和BIO没啥区别,也是会阻塞当前线程(Java目前没有协程,所以阻塞当前方法就等价于阻塞当前线程,建议用回调的方式,read是给出回调方法,有数据了则通过回调方法来处理获取数据后的业务逻辑(这个时候底层也是用到来类似Selector);

标签:BIO,NIO,阻塞,AIO,线程,IO,缓冲区,数据,socket
From: https://www.cnblogs.com/silentdoer/p/17515212.html

相关文章

  • 解决minio使用nginx代理出现问题(上传文件可以,创建桶404)
    minio使用nginx代理出现问题(上传文件可以,创建桶失败)server{listen80;#error_page500502503504404/404.html;注释掉location/{proxy_set_headerX-Forwarded-Proto$scheme;proxy_set_headerX-Real-IP$remote_addr;......
  • 离线安装mysql报错解决方法:/usr/sbin/mysqld: error while loading shared libraries:
    Linux:centos7.664位mysql:5.6使用离线方式安装:rpm-ivh--nodepsmysql*,执行systemctlstartmysqld.service发现启动不了,通过vi/var/log/mysql.log看到如下关键字:libraries:libaio.so.1,之前也是按照网上帖子各种修改都没有解决问题,详细报错如下:/usr/sbin/mysqld:error......
  • biog3
    前言 pta第6到第8次作业来说,重点就是成绩管理系统,逐渐迭代,除pta6以外,剩下两次作业还添加了一些其他的小题目,主要考察我们Java中的一些其他的知识点。题量不算大,甚至pta6只有一题,就是课程成绩管理系统由于课程成绩管理系统的类图以给出,课程管理系统较之前的点菜系统来说......
  • 利用freemarker和minIO生成文章详情html并存入minIO
    packagecom.heima.article.test;importcom.alibaba.fastjson.JSONArray;importcom.baomidou.mybatisplus.core.toolkit.StringUtils;importcom.baomidou.mybatisplus.core.toolkit.Wrappers;importcom.heima.article.ArticleApplication;importcom.heima.article.......
  • (转)基于velero+minio对k8s进行备份和恢复
    原文:https://www.cnblogs.com/cyh00001/p/16548774.html一、velero介绍Velero是由vmware公司团队研发开源工具,用于安全地备份、恢复和迁移Kubernetes集群和持久卷。它可以在本地和公共云中运行。Velero由一个在您的Kubernetes集群中作为部署运行的服务器进程和一个命令行......
  • MinIO——分布式文件系统
    对象如图片、视频、文档等存储方式对比:优点缺点服务器磁盘:开发便捷、成本低扩展困难分布式文件系统:容易实现扩容复杂度高    第三方存储:开发简单,功能强大,免维护......
  • Java NIO
    NIO主要有三大核心部分:Channel(通道)、Buffer(缓冲区)、Selector。传统IO基于字节流和字符流进行操作,而NIO基于Channel和Buffer(缓冲区)进行操作,数据总是从通道读取到缓冲区中,或者从缓冲区写入到通道中。Selector(选择区)用于监听多个通道的事件(比如:连接打开、数据达到)。因此,单个线程可......
  • Bios.Boot 系统引导修复
    Windowswin修复引导相对比较简单,下一个wepe或是其他任意PE系统都会自带修复引导功能Linux/Ubuntulinux这里只介绍Ubuntu的修复引导方式,其他发行版原理大差不差。注意是efi启动模式,如果是传统引导模式,此教程并不适用。1.使用安装盘,跳过安装界面,进入试用系统(注意版本应使用对应......
  • 【大数据】通过 docker-compose 快速部署 MinIO 保姆级教程
    目录一、概述二、MinIO与Ceph对比1)架构设计对比2)数据一致性对比3)部署和管理对比4)生态系统和兼容性对比三、前期准备1)部署docker2)部署docker-compose四、创建网络五、MinIO编排部署1)下载MinIO安装包2)配置3)启动脚本bootstrap.sh4)构建镜像Dockerfile5)编排docker-compose.......
  • SMBIOS(System Management BIOS)是一种在计算机系统中提供硬件信息的规范,定义了一组结构
    SMBIOS(SystemManagementBIOS)是一种在计算机系统中提供硬件信息的规范,定义了一组结构化的数据格式,用于描述计算机系统的硬件配置。SMBIOS版本即指SMBIOS规范的版本号。SMBIOS规范由DMI(DesktopManagementInterface)工作组制定,旨在通过标准化的方式获取和展示系统硬件信息,以便操......