BIO

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

当客户端建立连接后,服务端会开辟线程用来与客户端进行连接。以下两种情况会造成IO阻塞:

  1. 服务端会一直阻塞,直到和客户端进行连接
  2. 客户端也会一直阻塞,直到和服务端进行连接

基于BIO,当连接时,每有一个客户端,服务就开启线程处理,这样对资源的占用时非常大的;如果使用线城市来做优化,当大量连接时,服务端也会面临无空闲线程处理的问题。那么怎么设计才能让单个线程能够处理更多请求,而不是一个。所以NIO就被提出。

NIO

NIO(Non Blocking IO)又称同步非阻塞IO。服务器实现模式为把多个连接(请求)放入集合中,只用一个线程可以处理多个请求(连接),也就是多路复用。

NIO有3大核心组件:

  1. Buffer:缓冲区,buffer 底层就是数组
  2. Channel:通道,channel 类似于流,每个 channel 对应一个 buffer缓冲区
  3. Selector:多路复用器,channel 会注册到 selector 上,由 selector 根据 channel 读写事件的发生将其交由某个空闲的线程处理

这样就大大提升了连接的数量,用于接收请求。

NIO目前有三个函数(模型)

  • select
  • poll
  • epoll

Select函数

Select 是Linux提供的一个函数,可以将一批fd一次性传递给内核,然后由内核去遍历,来确定哪个fd符合,并提供给用户空间

Select 函数处理过程

  1. 将用户空间的fd数组拷贝到内核空间
  2. 内核空间会遍历fd数组,查看是否有数据到达
    1. 遍历所有fd,将当前进程挂到每个fd的等待队列中
    2. 当设备收到一条消息(网络设备)或填写完文件数据(磁盘设备)后,会唤醒设备等待队列上睡眠的进程,随后当前进程就会被唤醒
  3. 遍历完成后,如果有数据到达,返回有数据到达的fd的数量,并对用户空间的fd标记
  4. 如果无数据到达,则当前进程进入睡眠,当有某个fdI/O事件或当前进程睡眠超时后,当前进程重新唤醒再次遍历所有fd文件
  5. 用户空间再此循环遍历,没有标记fd 不处理,只有标记fd才会去处理

Select存在的问题

  1. fd数量有限制:单个进程所打开的fd是有限制的,通过 FD_SETSIZE 设置,默认1024
  2. fd拷贝耗时:每次调用 select,需要将fd数组从用户空间拷贝到内核空间
  3. 内核空间遍历耗时:内核空间通过遍历的方式,查看fd是否有数据到达,这是一个同步的过程
  4. 找到fd后,返回的是数量,而不是fd本身select返回的是fd的数量,具体是哪个还需要用户自己遍历

Poll函数

Poll 也是Linux提供的内核函数,pollselect 基本是一致,唯一的区别在于它们支持的fd的数量不一致

  • select : 只能监听 1024 个fd
  • poll :无限制,操作系统支持多少,poll 就可以支持多少

Epoll函数

poll解决了select函数的fd数量问题,而epoll解决了selectpoll函数其余问题:

  1. fd数量有限制poll已经解决此问题
  2. fd拷贝耗时:内核空间种保存一份fd数组,无需用户每次都重新传入,只需要告诉内核修改的部分即可
  3. 内核空间遍历耗时:内核空间不再通过遍历的方式找fd,而是通过异步 IO 事件唤醒
  4. 找到fd后,返回的是数量,而不是fd本身:内核空间会通过异步 IO 事件,将fd返回给用户,用户无需在遍历整个fd数组

因此,epoll提供3 个函数,来处理上述改进的方案:

  1. epoll_create:创建 epoll 句柄
  2. epoll_ctl:向内核空间添加,修改,删除需要监控的fd
  3. epoll_waitepoll_pwait:类似 select 函数

BIO和NIO的区别和原理的更多相关文章

  1. NIO 源码分析(03) 从 BIO 到 NIO

    目录 一.NIO 三大组件 Channels.Buffers.Selectors 1.1 Channel 和 Buffer 1.2 Selector 1.3 Linux IO 和 NIO 编程的区别 ...

  2. 面试官:BIO、NIO、AIO是什么,他们有什么区别?

    哈喽!大家好,我是小奇,一位热爱分享的程序员 小奇打算以轻松幽默的对话方式来分享一些技术,如果你觉得通过小奇的文章学到了东西,那就给小奇一个赞吧 文章持续更新 一.前言 书接上回,感觉上次的公司氛围不 ...

  3. BIO、NIO与NIO.2的区别与联系

    BIO.NIO.NIO.2之间的区别主要是通过同步/异步.阻塞/非阻塞来进行区分的 同步: 程序与操作系统进行交互的时候采取的是问答的形式 异步: 程序与操作系统取得连接后,操作系统会主动通知程序消息 ...

  4. BIO与NIO、AIO的区别

    IO的方式通常分为几种,同步阻塞的BIO.同步非阻塞的NIO.异步非阻塞的AIO. 一.BIO      在JDK1.4出来之前,我们建立网络连接的时候采用BIO模式,需要先在服务端启动一个Serve ...

  5. [转帖] BIO与NIO、AIO的区别

    培训里面讲的东西  自己查了下 啥意思,,, 转帖强化一下. http://blog.csdn.net/skiof007/article/details/52873421 IO的方式通常分为几种,同步 ...

  6. BIO与NIO、AIO的区别(这个容易理解)

    转自:http://blog.csdn.net/skiof007/article/details/52873421 BIO与NIO.AIO的区别(这个容易理解) IO的方式通常分为几种,同步阻塞的BI ...

  7. 以Java的视角来聊聊BIO、NIO与AIO的区别?

    转: 以Java的视角来聊聊BIO.NIO与AIO的区别? 飞丫玲丫 17-07-2623:10 题目:说一下BIO/AIO/NIO 有什么区别?及异步模式的用途和意义? BIO(Blocking I ...

  8. JAVA BIO与NIO、AIO的区别

    IO的方式通常分为几种,同步阻塞的BIO.同步非阻塞的NIO.异步非阻塞的AIO. 一.BIO 在JDK1.4出来之前,我们建立网络连接的时候采用BIO模式,需要先在服务端启动一个ServerSock ...

  9. BIO与NIO、AIO的区别(转)

    IO的方式通常分为几种,同步阻塞的BIO.同步非阻塞的NIO.异步非阻塞的AIO. 一.BIO 在JDK1.4出来之前,我们建立网络连接的时候采用BIO模式,需要先在服务端启动一个ServerSock ...

  10. [转帖]JAVA BIO与NIO、AIO的区别(这个容易理解)

    JAVA BIO与NIO.AIO的区别(这个容易理解) https://blog.csdn.net/ty497122758/article/details/78979302 2018-01-05 11 ...

随机推荐

  1. k8s上安装elasticsearch集群

    官方文档地址:https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-quickstart.html yaml文件地址:https://dow ...

  2. 2_Docker

    一. Docker介绍 1.1 引言 场景1: 我本地运行没问题啊 环境问题 场景2: 哪个哥们又写死循环了, 怎么这么卡 在多用户的操作系统下, 会相互影响 场景3: 淘宝在双11的时候, 用户量暴 ...

  3. 【持久层框架】- SpringData - JPA

    SpringData - JPA 生命不息,写作不止 继续踏上学习之路,学之分享笔记 总有一天我也能像各位大佬一样 一个有梦有戏的人 @怒放吧德德 分享学习心得,欢迎指正,大家一起学习成长! JPA简 ...

  4. P5657 [CSP-S2019] 格雷码 (找规律)

    观察几个数据,有一种思路:类似于二分,判断每一位应该填1还是0: 1 #include <bits/stdc++.h> 2 //#define loveGsy 3 using namesp ...

  5. HDU2196 Computer (树形DP-换根)

    dp[u][0]表示u向下走的最大距离: dp[u][1]表示u向下走的次大距离: dp[u][2]表示u向上走的最大距离: 最后的答案就是每个点的max(dp[u][0],dp[u][2]); 求解 ...

  6. SSM整合以及相关补充

    SSM整合以及相关补充 我们在前面已经学习了Maven基本入门,Spring,SpringMVC,MyBatis三件套 现在我们来通过一些简单的案例,将我们最常用的开发三件套整合起来,进行一次完整的项 ...

  7. 代码随想录第八天 |344.反转字符串 、541. 反转字符串II、剑指Offer 05.替换空格 、151.翻转字符串里的单词 、剑指Offer58-II.左旋转字符串

    第一题344.反转字符串 编写一个函数,其作用是将输入的字符串反转过来.输入字符串以字符数组 s 的形式给出. 不要给另外的数组分配额外的空间,你必须原地修改输入数组.使用 O(1) 的额外空间解决这 ...

  8. Vue3 Vite3 状态管理 pinia 基本使用、持久化、在路由守卫中的使用

    在<基于 vite 创建 vue3 项目>一文中整合了 pinia,有不少伙伴不知道 pinia 是什么,本文简单介绍 pinia.主要包括三方面: pinia 的基本用法,在<基于 ...

  9. 如何使用 pyqt 读取串口传输的图像

    前言 这学期选修了嵌入式系统的课程,大作业选择的题目是人脸口罩检测.由于课程提供的开发板搭载的芯片是 STM32F103ZET6,跑不动神经网络,所以打算将 OV7725 拍摄到的图像通过串口传输给上 ...

  10. GitHub Pages 和 Jekyll 笔记

    GitHub Pages 和 Jekyll 笔记 快速创建(使用默认的Jekyll引擎) 1. 新建仓库 新建一个空仓库, 名称为username.github.io, 其中 username 就是你 ...