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. Elasticsearch单字段支持的最大字符数

    ignore_above的作用 ES中用于设置超过设定字符后,不被索引或者存储. 当字符超过给定长度后,能否存入 keyword类型的最大支持的长度为--32766个UTF-8类型的字符. 也就是说t ...

  2. k8s中节点级别的日志

    容器化应用程序写入到 stdout 和 stderr 中的任何信息,都将被容器引擎重定向到某个地方.例如,Docker 容器引擎将 stdout 和 stderr 这两个输出流重定向到 logging ...

  3. 5.监控MySQL

    prometheus监控MySQL需要用到mysql_exporter. mysql_exporter 项目地址:https://github.com/prometheus/mysqld_export ...

  4. 使用gitlab+jenkins+nexus拉取springcloud并根据不同模块构建docker镜像,并推送到nexus里的docker仓库

    1.安装gitlab 详情看:https://www.cnblogs.com/sanduzxcvbnm/p/13023373.html 安装好gitlab后,然后创建一个普通用户,编辑用户,给用户设置 ...

  5. 7M与N的数学运算

    m=eval(input()) n=eval(input()) a=m+n b=m*n c=m**n d=m%n e=max(m,n) print(a,b,c,d,e)

  6. NSIS皮肤插件:vcl-styles-plugins

    vcl-styles-plugins简介   NSISVCLStyles  plugin (dll)是一款应用于nsis安装程序的皮肤插件,插件大小约为1.6MB,实际应用在安装程序中压缩后约为550 ...

  7. python中的多线程与多进程

    线程概念: 线程也叫轻量级进程,是操作系统能够进行运算调度的最小单位,它被包涵在进程之中,是进程中的实际运作单位. 线程自己不拥有系统资源,只拥有一点儿在运行中必不可少的资源,但它可与同属一个进程的其 ...

  8. Mysql编程中遇到的小错误

    我在mysql中创建的数据库表语句为如下 create table grade (id int not null, name varchar(255), desc varchar(255), prim ...

  9. 方法的重载(overload)

    1.定义:在同一个类中,允许存在一个以上的同名方法,只要它们的参数个数或者参数类型不同即可. "两同一不同":同一个类.相同方法名 参数列表不同:参数个数不同,参数类型不同 2.举 ...

  10. System.IO.FileSystemWatcher的坑

    System.IO命名空间下面有一个FileSystemWatcher,这个东西可以实现文件变动的提醒.需要监控文件夹变化(比如FTP服务器)的情形非常适用. 需要监控文件新建时,我们可以这么写: _ ...