BIO和NIO的区别和原理
BIO
BIO(Blocking IO) 又称同步阻塞IO,一个客户端由一个线程来进行处理

当客户端建立连接后,服务端会开辟线程用来与客户端进行连接。以下两种情况会造成IO阻塞:
- 服务端会一直阻塞,直到和客户端进行连接
- 客户端也会一直阻塞,直到和服务端进行连接
基于BIO,当连接时,每有一个客户端,服务就开启线程处理,这样对资源的占用时非常大的;如果使用线城市来做优化,当大量连接时,服务端也会面临无空闲线程处理的问题。那么怎么设计才能让单个线程能够处理更多请求,而不是一个。所以NIO就被提出。
NIO
NIO(Non Blocking IO)又称同步非阻塞IO。服务器实现模式为把多个连接(请求)放入集合中,只用一个线程可以处理多个请求(连接),也就是多路复用。
NIO有3大核心组件:
- Buffer:缓冲区,buffer 底层就是数组
- Channel:通道,channel 类似于流,每个 channel 对应一个 buffer缓冲区
- Selector:多路复用器,channel 会注册到 selector 上,由 selector 根据 channel 读写事件的发生将其交由某个空闲的线程处理

这样就大大提升了连接的数量,用于接收请求。
NIO目前有三个函数(模型)
- select
- poll
- epoll
Select函数
Select 是Linux提供的一个函数,可以将一批fd一次性传递给内核,然后由内核去遍历,来确定哪个fd符合,并提供给用户空间

Select 函数处理过程
- 将用户空间的
fd数组拷贝到内核空间 - 内核空间会遍历
fd数组,查看是否有数据到达- 遍历所有
fd,将当前进程挂到每个fd的等待队列中 - 当设备收到一条消息(网络设备)或填写完文件数据(磁盘设备)后,会唤醒设备等待队列上睡眠的进程,随后
当前进程就会被唤醒
- 遍历所有
- 遍历完成后,如果有数据到达,返回有数据到达的
fd的数量,并对用户空间的fd做标记 - 如果无数据到达,则
当前进程进入睡眠,当有某个fd有I/O事件或当前进程睡眠超时后,当前进程重新唤醒再次遍历所有fd文件 - 用户空间再此循环遍历,没有标记的
fd不处理,只有标记的fd才会去处理
Select存在的问题
fd数量有限制:单个进程所打开的fd是有限制的,通过FD_SETSIZE设置,默认1024fd拷贝耗时:每次调用select,需要将fd数组从用户空间拷贝到内核空间- 内核空间遍历耗时:内核空间通过遍历的方式,查看
fd是否有数据到达,这是一个同步的过程 - 找到
fd后,返回的是数量,而不是fd本身:select返回的是fd的数量,具体是哪个还需要用户自己遍历
Poll函数
Poll 也是Linux提供的内核函数,poll 和 select 基本是一致,唯一的区别在于它们支持的fd的数量不一致
- select : 只能监听 1024 个
fd - poll :无限制,操作系统支持多少,poll 就可以支持多少
Epoll函数
poll解决了select函数的fd数量问题,而epoll解决了select、poll函数其余问题:
fd数量有限制:poll已经解决此问题fd拷贝耗时:内核空间种保存一份fd数组,无需用户每次都重新传入,只需要告诉内核修改的部分即可- 内核空间遍历耗时:内核空间不再通过遍历的方式找
fd,而是通过异步 IO 事件唤醒 - 找到
fd后,返回的是数量,而不是fd本身:内核空间会通过异步 IO 事件,将fd返回给用户,用户无需在遍历整个fd数组

因此,epoll提供3 个函数,来处理上述改进的方案:
epoll_create:创建 epoll 句柄epoll_ctl:向内核空间添加,修改,删除需要监控的fdepoll_wait、epoll_pwait:类似select函数
BIO和NIO的区别和原理的更多相关文章
- NIO 源码分析(03) 从 BIO 到 NIO
目录 一.NIO 三大组件 Channels.Buffers.Selectors 1.1 Channel 和 Buffer 1.2 Selector 1.3 Linux IO 和 NIO 编程的区别 ...
- 面试官:BIO、NIO、AIO是什么,他们有什么区别?
哈喽!大家好,我是小奇,一位热爱分享的程序员 小奇打算以轻松幽默的对话方式来分享一些技术,如果你觉得通过小奇的文章学到了东西,那就给小奇一个赞吧 文章持续更新 一.前言 书接上回,感觉上次的公司氛围不 ...
- BIO、NIO与NIO.2的区别与联系
BIO.NIO.NIO.2之间的区别主要是通过同步/异步.阻塞/非阻塞来进行区分的 同步: 程序与操作系统进行交互的时候采取的是问答的形式 异步: 程序与操作系统取得连接后,操作系统会主动通知程序消息 ...
- BIO与NIO、AIO的区别
IO的方式通常分为几种,同步阻塞的BIO.同步非阻塞的NIO.异步非阻塞的AIO. 一.BIO 在JDK1.4出来之前,我们建立网络连接的时候采用BIO模式,需要先在服务端启动一个Serve ...
- [转帖] BIO与NIO、AIO的区别
培训里面讲的东西 自己查了下 啥意思,,, 转帖强化一下. http://blog.csdn.net/skiof007/article/details/52873421 IO的方式通常分为几种,同步 ...
- BIO与NIO、AIO的区别(这个容易理解)
转自:http://blog.csdn.net/skiof007/article/details/52873421 BIO与NIO.AIO的区别(这个容易理解) IO的方式通常分为几种,同步阻塞的BI ...
- 以Java的视角来聊聊BIO、NIO与AIO的区别?
转: 以Java的视角来聊聊BIO.NIO与AIO的区别? 飞丫玲丫 17-07-2623:10 题目:说一下BIO/AIO/NIO 有什么区别?及异步模式的用途和意义? BIO(Blocking I ...
- JAVA BIO与NIO、AIO的区别
IO的方式通常分为几种,同步阻塞的BIO.同步非阻塞的NIO.异步非阻塞的AIO. 一.BIO 在JDK1.4出来之前,我们建立网络连接的时候采用BIO模式,需要先在服务端启动一个ServerSock ...
- BIO与NIO、AIO的区别(转)
IO的方式通常分为几种,同步阻塞的BIO.同步非阻塞的NIO.异步非阻塞的AIO. 一.BIO 在JDK1.4出来之前,我们建立网络连接的时候采用BIO模式,需要先在服务端启动一个ServerSock ...
- [转帖]JAVA BIO与NIO、AIO的区别(这个容易理解)
JAVA BIO与NIO.AIO的区别(这个容易理解) https://blog.csdn.net/ty497122758/article/details/78979302 2018-01-05 11 ...
随机推荐
- 使用nginx-ingress-controller配置https,但是再同时配置使用http
默认情况下,如果为该 Ingress 启用了 TLS,控制器会使用 308 永久重定向响应将 HTTP 客户端重定向到 HTTPS 端口 443.( Ingress 里配置了 https 证书的话,默 ...
- PAT (Basic Level) Practice 1030 完美数列 分数 25
给定一个正整数数列,和正整数 p,设这个数列中的最大值是 M,最小值是 m,如果 M≤mp,则称这个数列是完美数列. 现在给定参数 p 和一些正整数,请你从中选择尽可能多的数构成一个完美数列. 输入格 ...
- 18-基于CentOS7搭建RabbitMQ3.10.7集群镜像队列+HaProxy+Keepalived高可用架构
集群架构 虚拟机规划 IP hostname 节点说明 端口 控制台地址 192.168.247.150 rabbitmq.master rabbitmq master 5672 http://192 ...
- SpringMVC访问静态资源的问题。
在项目中引用css和js文件一直出错,反复修改文件路径始终访问不到.究其原因原来是应该在web.xml 文件中添加访问静态资源的默认servlet. 如下. <servlet-mapping&g ...
- Can not set int field xxx to java.lang.Long 错误
Can not set int field xxx to java.lang.Long 错误 这个错误其实是因为Java程序和MySQL表中字段的属性匹配不一致 我的报错是Can not set ja ...
- SpringBoot 2.5.5整合轻量级的分布式日志标记追踪神器TLog
TLog能解决什么痛点 随着微服务盛行,很多公司都把系统按照业务边界拆成了很多微服务,在排错查日志的时候.因为业务链路贯穿着很多微服务节点,导致定位某个请求的日志以及上下游业务的日志会变得有些困难. ...
- 虚拟化_Xen——敬请期待!
更改Workstation兼容性为12.x,选择系统版本为RHEL6-64位,安装XenServer7.6成功!
- Vue学习之--------列表排序(ffilter、sort、indexOf方法的使用)、Vue检测数据变化的原理(2022/7/15)
文章目录 1.列表排序 1.1 .代码实例 1.2 .测试效果 1.3.需要掌握的前提知识 2.Vue监测数据变化的原理 2.1.代码实例 2.2 .测试效果 3.Vue检测数据的原理 3.1 基本知 ...
- LcdTools如何编写MIPI指令(初始化代码)
在LcdTools帮助文档中查看MIPI读写指令描述,如下图 编写LCM初始化代码就是配置LCM Driver IC寄存器值,一般只需用MipiWrite()指令写参数即可:下面介绍MipiWrite ...
- 43.Permission源码解析和自定义权限类
drf的权限类位于permission模块 如何确定权限 认证.限流,权限决定是否应该接收请求或拒绝访问 权限检查在视图的最开始处执行,在继续执行其他代码前 权限检查通常会使用request.us ...