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中打包好后自动上传到镜像仓库,…...

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

QHttpServer
QLineEdit-----输入提示 改动CmakeLists.txt 在帮助–索引查找QHttpServer 改动CmakeLists.txt,有三处改动 在谷歌浏览器测试,输入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"…...

Ansible 常用命令50条
以下是 Ansible 常用的 50 条命令: ansible --version: 查看 Ansible 版本信息。ansible all -m ping: 检查所有主机的连通性。ansible-playbook playbook.yml: 运行指定的 Ansible Playbook 文件。ansible-doc module_name: 查看指定模块的帮助文档。ansible-conf…...

ceph源码阅读 erasure-code
1、ceph纠删码 纠删码(Erasure Code)是比较流行的数据冗余的存储方法,将原始数据分成k个数据块(data chunk),通过k个数据块计算出m个校验块(coding chunk)。把nkm个数据块保存在不同的节点,通过n中的任意k个块还原出原始数据。EC包含编码和解…...

C++ 之 命名空间
namespace_百度百科,有示例...

MyBatis关系映射
文章目录 前言一、一对一映射1.1 创建实体1.2 xml配置 二、一对多映射2.1 创建实体2.2 resultMap配置2.3 测试 三、 多对多映射3.1 创建实体3.2 resultMap配置3.3 测试 前言 MyBatis是一个Java持久化框架,它提供了一种将数据库表和Java对象之间进行关系映射的方式。…...

DVWA失效的访问控制
失效的访问控制,可以认为是系统对一些功能进行了访问或权限限制,但因为种种原因,限制并没有生效,造成失效的访问控制漏洞,比如越权等 这里以DVWA为例,先访问低难度的命令执行并抓包 删除cookie,并在请求头…...

docker 笔记2 Docker镜像和数据卷
参考: 1.镜像是什么?(面试题) 是一种轻量级、可执行的独立软件包,它包含运行某个软件所需的所有内容,我们把应用程序和配置依赖打包好形成一个可交付的运行环境(包括代码、运行时需要的库、环境变量和配置文…...

java springboot 时间格式序列化 UTC8
背景 我们在项目中使用序列化和反序列化组件中,默认一般采用Jackson,如果遇到特殊配置,我们该怎么配置呢,大致有如下两种方式:采用配置文件【application.yml】和代码配置 配置文件 比如添加jackson节点 spring:jac…...

攻防世界-Get-the-key.txt
原题 解题思路 notepad看到,这应该是一个压缩包,解压。 但是解压的时候提示格式不对,不是zip,rar可以。解压出来有一个key.txt,打开就行。...

MyBatisPlus之DQL编程控制
🐌个人主页: 🐌 叶落闲庭 💨我的专栏:💨 c语言 数据结构 javaEE 操作系统 石可破也,而不可夺坚;丹可磨也,而不可夺赤。 MyBatisPlus之DQL编程控制 一、 条件查询方式&…...

本地使用GFPGAN进行图像人脸修复
人脸修复 1.下载项目和权重文件2.部署环境3.下载权重文件4.运行代码5.网页端体验 首先来看一下效果图 1.下载项目和权重文件 https://github.com/iptop/GFPGAN-for-Video.git2.部署环境 根据README文件部署好环境,额外还需要: cd GFPGAN-1.3.8 pyt…...