当前位置: 首页 > news >正文

NIO原理浅析(二)

IO分类

阻塞和非阻塞

阻塞IO:用户空间引发内核空间的系统调用,需要内核IO操作彻底完成之后,返回值才会返回到用户空间,执行用户的操作。阻塞指的用户空间程序的执行状态,用户空间程序需要等到IO操作彻底执行完毕。java中,默认创建的socket是阻塞的。

非阻塞IO:用户空间引发内核空间的系统调用,不需要等待内核IO操作彻底完成,内核立即给用户返回一个返回值。用户空间程序继续执行用户的操作,处于非阻塞的状态。java中,设置非阻塞的IO,以socket为例,见如下所示的代码:

serverChannel = ServerSocketChannel.open()
serverChannel.configureBlocking(false)

有兴趣,也可以参考java中关于Socket这个类的文档
在这里插入图片描述

同步和异步

同步IO:用户空间和内核空间的调用发起方式。同步IO是指用户空间的线程是主动发起IO请求的一方,内核空间是被动接受方。

异步IO:用户空间和内核空间的调用发起方式。异步IO是指用户空间的线程是被动接受方,但是内核空间里面的kernel是主动发起IO请求的一方。
在这里插入图片描述

四种常见的IO模型

服务器端的编程需要构造高性能的IO模型,常见的IO模型有四类:

在这里插入图片描述

同步阻塞IO(Blocking IO):

结合上面的描述,同步阻塞IO指的是用户空间主动发起的调用,然后需要等待内核空间将IO操作彻底完成之后才会返回用户空间,这期间,用户空间线程将会处于阻塞状态。
在这里插入图片描述

BIO优点: 程序简单,在阻塞等待数据的期间,用户挂起线程,用户线程基本不会占用CPU资源。

BIO缺点:每个请求可能会配置一套独立的线程,当并发量很高的场景下,内存和线程切换的成本很高。

应用举例:在Java中使用线程池的方式去连接数据库,就是使用的同步阻塞IO模型。

同步非阻塞IO(Non-blocking IO):

如果是socket被设置为non-blocking,NIO模型如果出现了系统调用,会出现以下两种情况:

(1)当内核缓存区里面没有数据,那么当用户空间发起的系统调用时,会立即返回一个失败的信息

(2)当内核缓存区里面有数据,那么当用户空间发起的系统调用时,会进入到阻塞状态,将内核缓存区里面的数据复制到用户缓冲区。直到数据返回成功,才会解除阻塞的状态。

在这里插入图片描述

NIO的优点:每次发起IO系统调用,线程在内核等待缓冲区数据的时候,会立即返回值,不会阻塞。实时性比较好。

NIO的缺点:需要不断地轮询发起系统调用,这样会占用大量的CPU时间,资源利用率很低。

IO多路复用(IO Multiplexing)

首先从字面意思来理解多路复用:

  • 多路: 多个socket网络连接

  • 复用:复用一个线程,使用一个线程来检查多个文件套接字(又称文件句柄)的就绪状态

IO多路复用是一种同步IO模型,实现用一个线程监视多个文件句柄,一旦有文件句柄准备就绪,就可以通知应用程序进行相应的读写操作。没有文件句柄就绪,就会阻塞应用程序,然后交出CPU的时间片。

通过对之前两种IO模型的总结,我们可以发现:

针对高并发的场景,同步阻塞模型的缺点是需要做频繁的内存和线程的切换,效率很低。同步非阻塞的缺点是要在用户程序空间轮询的发起系统调用,这导致内核态和用户态的频繁切换,也会消耗大量的资源。

IO多路复用则可以避免内核态和用户态的频繁切换,因为IO多路复用模型将轮询套接字(又称为文件句柄)的动作,直接放在了内核态进行,这样避免了内核态和用户态的频繁切换

举例说明

我们以基础的socket模型为例,展现IO多路复用的机制:

下面是基础的socket模型伪码:

listenSocket = socket(); //系统调用socket()函数,调用创建一个主动socket
bind(listenSocket); //给主动socket绑定地址和端口
listen(listenSocket); //将默认的主动socket转换成服务器使用的被动socket(也叫监听socket)
while(true) { //循环监听客户端的连接请求connectSocket = accept(listenSocket); //接受客户端连接,获取已连接socketrecv(connSocket); //从客户端读取数据,只能同时处理一个客户端send(connSocket); //给客户端返回数据,只能同时处理一个客户端
}

网络通信的流程如下图所示:
在这里插入图片描述

上图所示的socket网络通信,是典型的同步阻塞模型,当有大量客户端连接时,这种模型的处理性能比较差。使用IO多路复用可以解决这种困境。


linux中,操作系统提供了select、poll和epoll三种多路复用机制。

select机制

四个问题

1、IO多路复用可以最多监听多少个socket?

2、IO多路复用可以监听socket里面的哪些事件?

3、IO多路复用如何感知已经就绪的文件描述符fd?

4、IO多路复用如何实现网络通信?

首先在linux平台上查看一下select函数定义,可以参考一下文章1Linux内核select源码剖析 、文章2Linux select源码分析。

/**
* 参数说明
* 监听的文件描述符数量 __nfds
* 被监听描述符的三个集合*__readfds, *__writefds 和 *__exceptfds
* 监听时阻塞等待的超时时长*__timeout
* 返回值:返回一个socket对应的文件描述符
*/
int select(int __nfds, fd_set * __readfds, fd_set * __writefds, fd_set * __exceptfds, struct timeval * __timeout)

select函数监听的文件描述符被分成三类,分别是__readfds, __writefds 和 __exceptfds,当用户调用select时,假设当前监控的是___readfds集合,select操作会将需要监控___readfds集合从用户空间拷贝到内核空间,随后在内核空间一直遍历自身的skb(SocketBuffer),检查每个skb的poll逻辑,已确定socket是否存在可读事件。若没有socket可读,则会进入到睡眠状态。当发现有sokcet可读,则会唤醒用户空间的程序,然后在用户态去遍历监控的集合,并读取数据。

在这里插入图片描述

select 多路复用方法存在的缺陷:

1、调用select需要将套接字列表从用户态复制到内核态,对于多并发场景,资源消耗量比较大。

2、能监听的端口号的数量有限制,FD_SETSIZE,32位机器限制1024个套接字,64位机器限制2048个套接字。

3、被监控的fdlist列表,如果有一个套接字数据可读,业务就需要遍历一遍用户态的fdlist列表,时间复杂度O(n)。

poll

相较于select,poll优化了select的缺陷二,使用的是动态数组结构,而不是select的bitMap结构,突破了1024的限制,但是poll也没有解决缺陷1和缺陷3,仍然存在用户态到内核态的套接字复制而导致的资源消耗过大的问题。

相关文章:

NIO原理浅析(二)

IO分类 阻塞和非阻塞 阻塞IO:用户空间引发内核空间的系统调用,需要内核IO操作彻底完成之后,返回值才会返回到用户空间,执行用户的操作。阻塞指的用户空间程序的执行状态,用户空间程序需要等到IO操作彻底执行完毕。j…...

leetcode每日一练-第53题-最大子数组和

一、思路 动态规划 二、解题方法 使用了两个变量 maxSum 和 currentSum 来分别记录全局的最大和和当前连续子数组的和。遍历数组时,我们不断更新 currentSum,并比较是否需要更新 maxSum。最后,maxSum 就是最大的连续子数组和。 三、code …...

京东云接入【风险识别】接口

京东云的接入文档写的真的跟逗你玩一样,就给提供了一个简单的实例,其他的全靠自己摸索。 这篇文章描述的是激动云【风险识别接口】接入,也会介绍如何接入其他的一些未在文章内描述到的接口。 这里使用的是python SDK,先安装 pip…...

在 linux 虚拟机上安装配置 hive

目录 一 下载hive 安装包 二 解压 hive 并配置环境变量 三 配置hive 的配置文件 四 更新 guava 五 hive初始化 六 开启远程连接 七 使用datagrip 连接 hive 一 下载hive 安装包 百度网盘资源如下: 链接: https://pan.baidu.com/s/18jF-Qri0hc52_rtL61O0YQ?…...

作品集(陆续上传中)

智能家居---不断完善中 家居-CSDN直播 家居 语音刷抖音 --- 基于串口和adb 基于守护进程的语音刷抖音-CSDN直播 基于守护进程的语音刷抖音 海天一色项目 --- 船舶靠港零碳排加热器 FTP云盘 --- 多进程和socket FTP云盘-CSDN直播 FTP云盘...

论文解读 | 三维点云深度学习的综述

原创 | 文 BFT机器人 KITTI 是作为基准测试是自动驾驶中最具影响力的数据集之一,在学术界和工业界都被广泛使用。现有的三维对象检测器存在着两个限制。第一是现有方法的远程检测能力相对较差。其次,如何充分利用图像中的纹理信息仍然是一个开放性的问题…...

基于costas环的载波同步系统matlab性能仿真

目录 1.算法运行效果图预览 2.算法运行软件版本 3.部分核心程序 4.算法理论概述 5.算法完整程序工程 1.算法运行效果图预览 2.算法运行软件版本 matlab2022a 3.部分核心程序 ............................................................................ I_Dataroun…...

解码自我注意的魔力:深入了解其直觉和机制

一、说明 自我注意机制是现代机器学习模型中的关键组成部分,尤其是在处理顺序数据时。这篇博文旨在提供这种机制的详细概述,解释它是如何工作的,它的优点,以及它背后的数学原理。我们还将讨论它在变压器模型中的实现和多头注意力的…...

mysql之存储引擎

目录 存储引擎概念 MyISAM MyISAM特点 MyISAM 表的存储格式 MyISAM适用的生产场景 InnoDB InnoDB特点 选择存储引擎依据 MyISAM 和 INNODB区别 命令 查看系统支持的存储引擎 查看表使用的存储引擎 修改存储引擎 存储引擎概念 MySQL中的数据用各种不同的技术存…...

服务器日志出现大量NTLM(NT LAN Manager)攻击

日志名称:Security 来源: Microsoft-Windows-Security-Auditing 日期: 2023/8/30 20:57:40 事件 ID:4625 任务类别:登录 级别: 信息 关键字: 审核失败 用户: 暂缺 计算机: WIN-QBJ3ORTR0CF 描述: 帐户登录失败。 主题: 安全 ID:NULL SID 帐户名:- 帐户域:- …...

Spring学习|Spring简介、IOC控制反转理解、IOC创建对象方式

Spring Spring:春天------>给软件行业带来了春天! 2002,首次推出了Spring框架的雏形: interface21框架! Spring框架即以interface21框架为基础,经过重新设计,并不断丰富其内涵,于2004年3月24日发布了1.0正式版。 RodJohnson,Spring Framework创始人&…...

DDR2 IP核调式记录2

本文相对简单,只供自己看看就行。从其它的博客找了个代码,然后记录下仿真波形。 1. 功能 直接使用quartus生成的DDR2 IP核,然后实现循环 -->写入burst长度的数据后读出。 代码数据的传输是32位,实际使用了两片IC。因此IP核也是…...

【ES6】js 中class的extends、super关键字用法和避坑点

在JavaScript中,使用class关键字可以实现面向对象编程。其中,extends和super是两个非常重要的关键字,它们分别用于实现类的继承和调用父类的方法。 一、extends关键字 extends关键字用于实现类的继承,它可以让一个子类继承父类的…...

mysql排名函数row_number()over(order by)和with * as 的用法

601. 体育馆的人流量(力扣mysql题,难度:困难) 表:Stadium ------------------------ | Column Name | Type | ------------------------ | id | int | | visit_date | date | | people | int | ------------------------vis…...

linux局域网IP地址冲突检测

使用keepalived设置vip的时候,发现vip无法连接,经查是出现了ip地址冲突,使用了一个在用的ip作为了vip,但是这个ip其实ping不通,因为目标机禁用了ping,也即是丢弃了ICMP包。 一、那么怎么检测IP地址是否已经…...

远距离WiFi模组方案,实现移动设备之间高效通信,无人机远程图传应用

随着科技的不断进步,无线通信技术也在日新月异地发展。其中,WiFi技术已经成为现代生活中不可或缺的一部分。 从室内到室外,WiFi的应用场景正在不断扩大,为我们的日常生活和工业生产带来了极大的便利。 WiFi技术,即无…...

Docker构建Springboot项目,并发布测试

把SpringBoot项目打包成Docker镜像有两种方案: 全自动化:先打好docker镜像仓库,然后在项目的maven配置中配置好仓库的地址,在项目里配置好Dockerfile文件,这样可以直接在idea中打包好后自动上传到镜像仓库&#xff0c…...

flutter架构全面解析

Flutter 是一个跨平台的 UI 工具集,它的设计初衷,就是允许在各种操作系统上复用同样的代码,例如 iOS 和 Android,同时让应用程序可以直接与底层平台服务进行交互。如此设计是为了让开发者能够在不同的平台上,都能交付拥…...

QHttpServer

QLineEdit-----输入提示 改动CmakeLists.txt 在帮助–索引查找QHttpServer 改动CmakeLists.txt&#xff0c;有三处改动 在谷歌浏览器测试&#xff0c;输入127.0.0.1/api/login 测试代码 #include<QCoreApplication> #include <QHttpServer> //http服务器 int m…...

21.3 CSS 背景属性

1. 背景颜色 background-color属性: 设置元素的背景颜色. 它可以接受各种颜色值, 包括命名颜色, 十六进制颜色码, RGB值, HSL值等.快捷键: bctab background-color:#fff;<!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"…...

Vue3 + Element Plus + TypeScript中el-transfer穿梭框组件使用详解及示例

使用详解 Element Plus 的 el-transfer 组件是一个强大的穿梭框组件&#xff0c;常用于在两个集合之间进行数据转移&#xff0c;如权限分配、数据选择等场景。下面我将详细介绍其用法并提供一个完整示例。 核心特性与用法 基本属性 v-model&#xff1a;绑定右侧列表的值&…...

【Redis技术进阶之路】「原理分析系列开篇」分析客户端和服务端网络诵信交互实现(服务端执行命令请求的过程 - 初始化服务器)

服务端执行命令请求的过程 【专栏简介】【技术大纲】【专栏目标】【目标人群】1. Redis爱好者与社区成员2. 后端开发和系统架构师3. 计算机专业的本科生及研究生 初始化服务器1. 初始化服务器状态结构初始化RedisServer变量 2. 加载相关系统配置和用户配置参数定制化配置参数案…...

让AI看见世界:MCP协议与服务器的工作原理

让AI看见世界&#xff1a;MCP协议与服务器的工作原理 MCP&#xff08;Model Context Protocol&#xff09;是一种创新的通信协议&#xff0c;旨在让大型语言模型能够安全、高效地与外部资源进行交互。在AI技术快速发展的今天&#xff0c;MCP正成为连接AI与现实世界的重要桥梁。…...

3-11单元格区域边界定位(End属性)学习笔记

返回一个Range 对象&#xff0c;只读。该对象代表包含源区域的区域上端下端左端右端的最后一个单元格。等同于按键 End 向上键(End(xlUp))、End向下键(End(xlDown))、End向左键(End(xlToLeft)End向右键(End(xlToRight)) 注意&#xff1a;它移动的位置必须是相连的有内容的单元格…...

有限自动机到正规文法转换器v1.0

1 项目简介 这是一个功能强大的有限自动机&#xff08;Finite Automaton, FA&#xff09;到正规文法&#xff08;Regular Grammar&#xff09;转换器&#xff0c;它配备了一个直观且完整的图形用户界面&#xff0c;使用户能够轻松地进行操作和观察。该程序基于编译原理中的经典…...

鸿蒙DevEco Studio HarmonyOS 5跑酷小游戏实现指南

1. 项目概述 本跑酷小游戏基于鸿蒙HarmonyOS 5开发&#xff0c;使用DevEco Studio作为开发工具&#xff0c;采用Java语言实现&#xff0c;包含角色控制、障碍物生成和分数计算系统。 2. 项目结构 /src/main/java/com/example/runner/├── MainAbilitySlice.java // 主界…...

Mobile ALOHA全身模仿学习

一、题目 Mobile ALOHA&#xff1a;通过低成本全身远程操作学习双手移动操作 传统模仿学习&#xff08;Imitation Learning&#xff09;缺点&#xff1a;聚焦与桌面操作&#xff0c;缺乏通用任务所需的移动性和灵活性 本论文优点&#xff1a;&#xff08;1&#xff09;在ALOHA…...

云原生安全实战:API网关Kong的鉴权与限流详解

&#x1f525;「炎码工坊」技术弹药已装填&#xff01; 点击关注 → 解锁工业级干货【工具实测|项目避坑|源码燃烧指南】 一、基础概念 1. API网关&#xff08;API Gateway&#xff09; API网关是微服务架构中的核心组件&#xff0c;负责统一管理所有API的流量入口。它像一座…...

作为测试我们应该关注redis哪些方面

1、功能测试 数据结构操作&#xff1a;验证字符串、列表、哈希、集合和有序的基本操作是否正确 持久化&#xff1a;测试aof和aof持久化机制&#xff0c;确保数据在开启后正确恢复。 事务&#xff1a;检查事务的原子性和回滚机制。 发布订阅&#xff1a;确保消息正确传递。 2、性…...

pikachu靶场通关笔记19 SQL注入02-字符型注入(GET)

目录 一、SQL注入 二、字符型SQL注入 三、字符型注入与数字型注入 四、源码分析 五、渗透实战 1、渗透准备 2、SQL注入探测 &#xff08;1&#xff09;输入单引号 &#xff08;2&#xff09;万能注入语句 3、获取回显列orderby 4、获取数据库名database 5、获取表名…...