阻塞非阻塞IO(BIO和NIO),IO多路复用

news2024/9/25 1:17:11

1.概念

NIO(New Input/Output)和BIO(Blocking Input/Output)是Java中用于处理输入输出的两种不同的模型。

 

55201a5d1cba4de29eee7a7eae9961d3.png

BIO阻塞,等有了消息,立刻返回,一个线程处理一个recv(需要很多线程)。

NIO 有没有消息,都返回(但程序要自己判断,返回空就循环重复);一个线程可以处理多个recv(好处:不用很多线程;坏处:线程空转,cpu浪费严重)。

 

52ae4451f73d4d0c8ce0cb2c55740d5a.png

Java中新的NIO包可以通过上述形式设置是否开启阻塞,从而设置NIO或BIO,两者都支持;

 

IO多路复用

IO多路复用(IO Multiplexing)是一种通过单线程处理多个I/O操作的机制。它允许一个进程同时监听多个文件描述符(如Socket),并在有数据可读或可写时进行相应的处理,从而提高系统的并发性能。

在传统的阻塞I/O模型中,每个I/O操作都需要一个独立的线程来处理,当并发量增加时,线程数量会急剧增加,导致系统资源消耗过大。而使用IO多路复用,只需要一个线程就可以同时处理多个I/O操作,大大减少了线程的数量和系统开销。

常见的IO多路复用机制包括:

  1. select:select是Unix系统最早引入的IO多路复用机制。它通过select函数来监听多个文件描述符,当其中任意一个文件描述符准备就绪时,select函数会返回,然后可以通过遍历文件描述符集合来确定哪些文件描述符可读或可写。

  2. poll:poll是select的一种改进版本。它使用一个pollfd结构体数组来管理文件描述符,并通过poll函数来监听多个文件描述符的状态。与select相比,poll没有最大文件描述符数量的限制。

  3. epoll:epoll是Linux系统引入的一种高效的IO多路复用机制。它使用一个事件表来管理文件描述符,并通过epoll_ctl函数来注册和删除事件,通过epoll_wait函数来等待事件的发生。epoll提供了三种工作模式:边沿触发(EPOLLET)、水平触发(EPOLLIN、EPOLLOUT)和一次性触发(EPOLLONESHOT),可以根据具体需求选择适合的模式。(epoll可以理解为多了个记事本,)

IO多路复用适用于处理大量的并发连接,如服务器端的网络编程。它可以有效地减少线程的数量,提高系统的并发性能和资源利用率。

可以说:

select内核无状态,每次从零开始

eqoll内核维护一个状态,可以异步做很多事情,调用的时候能够立刻给出结果集

额外拓展

1.epoll机制详解

epoll是Linux系统引入的一种高效的IO多路复用机制,它提供了一种事件驱动的方式来处理多个文件描述符的I/O操作。相比于传统的select和poll机制,epoll在处理大量并发连接时具有更高的性能。

epoll的核心概念包括以下几个部分:

  1. epoll实例(epoll instance):epoll实例是一个内核数据结构,用于管理文件描述符和事件。通过epoll_create函数来创建一个epoll实例。

  2. 文件描述符(file descriptor):文件描述符是操作系统对文件或I/O设备的引用。在epoll中,需要将需要监听的文件描述符添加到epoll实例中。

  3. 事件(event):事件是对文件描述符的一种状态变化的表示,如可读、可写等。在epoll中,通过epoll_event结构体来表示事件。

  4. 事件表(event table):事件表是epoll实例中用来存储事件的数据结构,可以通过epoll_ctl函数来注册和删除事件。

epoll的工作流程如下:

  1. 创建epoll实例:通过epoll_create函数创建一个epoll实例,并返回一个文件描述符,用于后续的操作。

  2. 添加文件描述符:通过epoll_ctl函数将需要监听的文件描述符添加到epoll实例中,并指定需要监听的事件类型。

  3. 等待事件:通过epoll_wait函数等待事件的发生。当有文件描述符的事件发生时,epoll_wait函数会返回,并将事件信息填充到一个epoll_event数组中。

  4. 处理事件:遍历epoll_event数组,根据事件类型进行相应的处理。

  5. 循环操作:重复执行等待事件和处理事件的过程,实现持续的事件驱动。

epoll提供了三种工作模式:

  1. 边沿触发(EPOLLET):只有在文件描述符状态发生变化时才触发事件,适用于高效处理大量的并发连接。

  2. 水平触发(EPOLLIN、EPOLLOUT):只要文件描述符处于可读或可写状态,就会触发事件,适用于普通的网络编程。

  3. 一次性触发(EPOLLONESHOT):只触发一次事件,需要在处理完事件后重新注册。

epoll的优势在于可以处理大量的并发连接,具有更高的性能和资源利用率。它避免了传统select和poll机制中遍历文件描述符集合的开销,同时提供了更灵活的事件触发方式。因此,epoll被广泛应用于高性能的网络服务器编程。

2.BIO什么时候会阻塞?

BIO(Blocking I/O,阻塞I/O)是一种同步的I/O模型,在进行I/O操作时会阻塞当前线程,直到操作完成或出现错误。以下情况下,BIO会发生阻塞:

  1. 读取阻塞:当从输入流(如Socket的InputStream)读取数据时,如果没有可读取的数据,读取操作将会阻塞,直到有数据可读或者发生超时或错误。

  2. 写入阻塞:当向输出流(如Socket的OutputStream)写入数据时,如果输出缓冲区已满,写入操作将会阻塞,直到有空间可写或者发生超时或错误。

  3. 连接阻塞:在使用ServerSocket等待客户端连接时,accept()方法会阻塞当前线程,直到有客户端连接成功或发生超时或错误。

BIO的阻塞特性意味着在进行I/O操作时,线程会一直等待,不能处理其他任务。这可能导致资源浪费和性能下降。因此,对于高并发的网络应用,通常使用NIO(Non-blocking I/O,非阻塞I/O)或AIO(Asynchronous I/O,异步I/O)模型来避免阻塞。

3.上文提到的缓冲区(详解)

概念和作用:缓冲区(Buffer)是在进行I/O操作时用于临时存储数据的一块内存区域。它提供了一种缓冲数据的机制,可以减少实际的I/O操作次数,提高数据读写的效率。

在Java中,缓冲区是通过Buffer类的实例来表示的。Java NIO(New I/O)库提供了一组缓冲区类,如ByteBuffer、CharBuffer、ShortBuffer等,用于处理不同类型的数据。

缓冲区有以下几个重要的属性

  1. 容量(Capacity):缓冲区的容量表示它可以存储的最大数据量。一旦创建,缓冲区的容量就是固定的,不能改变。

  2. 位置(Position):缓冲区的位置表示当前读写操作的位置。初始时,位置为0,随着读写操作进行,位置会自动更新。

  3. 上界(Limit):缓冲区的上界表示有效数据的末尾位置。读写操作不能超过上界。

  4. 标记(Mark):缓冲区的标记是一个备忘位置,可以通过mark()方法设置,并通过reset()方法恢复到标记位置。

缓冲区的基本操作包括:

  1. 写入数据:通过put()方法将数据写入缓冲区,同时位置会自动向后移动。

  2. 读取数据:通过get()方法从缓冲区读取数据,同时位置会自动向后移动。

  3. 翻转缓冲区:通过flip()方法将上界设置为当前位置,位置重置为0,用于将缓冲区从写模式切换到读模式。

  4. 清空缓冲区:通过clear()方法将位置设置为0,上界设置为容量,用于将缓冲区从读模式切换到写模式。

缓冲区的使用可以提高I/O操作的效率,特别是在处理大量数据时。它可以减少系统的调用次数,提高数据读写的速度。

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/958142.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Solidity 小白教程:5. 变量数据存储和作用域 storage_memory_calldata

Solidity 小白教程:5. 变量数据存储和作用域 storage_memory_calldata Solidity 中的引用类型 引用类型(Reference Type):包括数组(array),结构体(struct)和映射(mapping&#xff…

用迅为RK3568开发板使用OpenCV处理图像颜色通道提取ROI

本小节代码在配套资料“iTOP-3568 开发板\03_【iTOP-RK3568 开发板】指南教程 \04_OpenCV 开发配套资料\07”目录下,如下图所示: 在计算机的色彩图像中存有三个通道,即 BGR 通道,根据三个颜色通道的亮度值来显示出不同的颜色&…

动态相对定位差分关键技术

载波相位测量:解决两个关键问题,即整周模糊度计算和周跳检测。 整周模糊度的快速固定是研究重点。目前成熟方法是模糊度协方差法,分为模糊度实数解估计和模糊度搜索两个过程。实数解估计通常采用kalman滤波,它为搜索算法提供搜索…

哈希表HashMap(基于vector和list)

C数据结构与算法实现(目录) 1 什么是HashMap? 我们这里要实现的HashMap接口不会超过标准库的版本(是一个子集)。 HashMap是一种键值对容器(关联容器),又叫字典。 和其他容易一样…

【Vue3 知识第一讲】Vue 简介、核心关键词解读

文章目录 前置导读1. 学习 Vue3 需要什么知识?2. 通过本课程将能学到什么? 第一章:Vue 简介1.1 核心关键词:构建用户界面1.2 核心关键词:框架1.2.1 库和框架的区别1.2.2 Vue 框架 1.3 核心关键词:渐进式&am…

CTFhub-SSRF-内网访问

CTFHub 环境实例 | 提示信息 http://challenge-8bf41c5c86a8c5f4.sandbox.ctfhub.com:10800/?url_ 根据提示,在url 后门添加 127.0.0.1/flag.php http://challenge-8bf41c5c86a8c5f4.sandbox.ctfhub.com:10800/?url127.0.0.1/flag.php ctfhub{a6bb51530c8f6be0…

模拟电子技术基础学习笔记一 本征半导体

半导体器件是构成电子电路的基本元件,它们所用的材料是经过特殊加工且性能可控的半导体材料。 1.本征半导体 纯净的具有晶体结构的半导体称为本征半导体 2.共价键 两个或多个原子通过共用电子对而产生的一种化学键称为共价键(covalent bond&#xff…

甄知携AIGC新升级产品参与首届人工智能生成内容国际会议,共探AIGC最前沿技术

首届人工智能生成内容国际会议(2023The 1st International Conference on AI-generated Content (AIGC2023)于2023年8月25-26日在中国上海举行。本次会议得到了复旦大学、中国科技大学、同济大学、上海交通大学、上海人工智能实验室、香港中文大学等知名院校和研究机构的大力支…

8.物联网LWIP,简要介绍http(超文本,URL),html(css,ajax),web实现打开灯

一。HTTP详解 1.超文本:(HyperText) (1)超文本文件彼此链接,形成网状(web),内含有超链接(Link)与各种媒体元素标记(Markup&#xff…

C#添加WebApi,配置Swagger

1、创建一个WebAPI项目 下载、安装、引入【Swashbuckle.AspNetCore】包 右击【解决方案】,然后点击【管理Nuget包】,搜索【Swashbuckle.AspNetCore】包 2、配置Swagger中间件 在【Startup.cs】文件中的【ConfigureService】类中添加如下代码。 在【Sta…

Git管理

Git管理 ①对于项目目录中有.git的,可以在idea里面更改远程提交地址 Git->>Manage Remotes 中修改远程提交地址 ②对于没有.git目录的项目 在项目的根目录下进入cmd,使用下面的语句初始化.git目录 ##初始化 git init

笔记本电脑连接不上wifi怎么办?3种方法轻松搞定!

在现代社会中,无线网络已经成为人们日常生活和工作中必不可少的一部分。然而,有时候我们可能会遇到笔记本电脑无法连接到Wi-Fi网络的问题。这种情况可能会让人感到困扰,影响正常的工作和娱乐体验。那笔记本电脑连接不上wifi怎么办呢&#xff…

VB:判断一个数是否为质数

VB编程:判断一个数是否为质数 Private Sub Command1_Click() 点击事件 Dim N%, I%, K% 定义N,I,K为整型 N Val(InputBox("N?")) 输入信息 K Int(Sqr(N)) 对N取平方根,并转换为整型 For I 2 To K 定义循环If N Mod I 0 Then Exit For Nex…

jenkins 发布job切换不同的jdk版本/ maven版本

1. 技术要求 因为有个新的项目需要使用jdk17 而旧的项目需要jdk1.8 这就需要jenkins在发布项目的时候可以指定jdk版本 2. 解决 jenkins全局工具配置页面 配置新的jdk 路径 系统管理-> 全局工具配置 如上新增个jdk 名称叫 jdk-17 然后配置jdk-17的根路径即可(这…

趣味微项目:玩转Python编程,轻松学习快乐成长!

💂 个人网站:【工具大全】【游戏大全】【神级源码资源网】🤟 前端学习课程:👉【28个案例趣学前端】【400个JS面试题】💅 寻找学习交流、摸鱼划水的小伙伴,请点击【摸鱼学习交流群】 在学习Python编程的旅程…

Mysql读取binlog并分析 binlog

1,Mysql 开启 binlog 配置文件中增加 [mysqld] log-binmysql-bin 2.常用 binlog命令 # 是否启用binlog日志 show variables like log_bin;# 查看详细的日志配置信息 show global variables like %log%;# 查看binlog的目录 show global variables like "%l…

无涯教程-Flutter - Dart简介

Dart是一种开源通用编程语言,它最初是由Google开发的, Dart是一种具有C样式语法的面向对象的语言,它支持诸如接口,类之类的编程概念,与其他编程语言不同,Dart不支持数组, Dart集合可用于复制数据…

The remote endpoint was in state [TEXT_FULL_WRITING]

报这个错是因为在websocket接收与发送消息时,资源互抢造成的,有很多帖子说将session锁住, 但是同一个账号多个客户端登陆的时候,session是不同的,所以只能锁住一个session,还是出现这个问题。 解决办法&a…

FPGA GTX aurora 8b/10b编解码 PCIE 视频传输,提供2套工程源码加QT上位机源码和技术支持

目录 1、前言免责声明 2、我这里已有的 GT 高速接口解决方案3、GTX 全网最细解读GTX 基本结构GTX 发送和接收处理流程GTX 的参考时钟GTX 发送接口GTX 接收接口GTX IP核调用和使用 4、设计思路框架视频源选择ADV7611解码芯片配置及采集动态彩条视频数据组包GTX aurora 8b/10b数据…

【Python】Web学习笔记_flask(7)——Jinja2模板(1)

Jinja2是基于python的模板引擎,功能类似于PHP的amarty、J2ee的Freemarker和velocity,完全支持Unicode,并具有集成的沙箱执行环境,Jinja2使用的事BSD协议,允许使用者修改和重新发布代码,也允许使用或在BSD代…