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

I/O模型


写在前面

前面聊完了IO方式, 也就意味着网络数据的收发通道是建立起来了。但业务场景中, 通道本身是不会发送数据的。在常见的网络应用中, server端会创建多个链接以服务更多client, 同时要求各个client尽可能互不影响。这是I/O模型(也就是IO方式+线程模型)要解决的问题。由于加入了线程要素, 接下来首先聊几个流行语。


一、常见词汇

1. 同步/异步

同步/异步是应用和内核之间的协作模式。由于Linux Kernel托管了对所有外设的I/O, 因此对外设的I/O操作都需要通过系统调用完成。一般来说, 应用发起I/O请求, 内核负责I/O响应。所以更严谨来说, I/O请求和I/O响应的协作。在应用发起I/O操作之后, 如果内核立刻开始处理, 这就是同步协作; 如果应用发起I/O之后, 内核并不马上开始处理, 那么就是异步协作。

2. 阻塞/非阻塞

阻塞/非阻塞则强调应用线程发起I/O操作后的状态。为什么应用线程状态? 因为应用开发者需要知道, 操作对当前线程状态的影响。类似地, 不强调内核状态是因为站在软件分层的角度应用不应该关心Kernel。此外, 虽然线程状态与前面所说的协作模式有关, 但是两者描述的对象不同。这个在面试中很容易掉坑, 比如讲讲同步和阻塞的区别。

3. 举个栗子

比如你(应用)用打印机(内核)打印文件

IO方式实例评价
同步阻塞IO你发起请求然后打印机立刻开始工作, 你站在打印机旁边等着啥也不干你投入发请求, 处理请求和接响应的时间
同步非阻塞IO你发起请求然后打印机立刻开始工作, 你继续忙手上的事情, 过了10分钟去拿结果你投入发请求, 检查进度和接响应的时间
异步阻塞IO你发起请求, 打印机就提示你文件已加入打印队列, 但是你就这么看着, 直到打印机把自己的文件打好你投入发请求, 处理请求(老板知道直挠头)和接响应的时间
异步非阻塞IO你发起请求, 打印机提示你10分钟去拿结果你投入发请求和接响应的时间

二、server端要点

  1. 服务于多用户(天南海北都能连接), 因此需要创建多个链接;
  2. 由于链接的独立性, 每个链接支持独立读写(各个链接的数据不会串门);
  3. 每个链接是自己创建的, 在数据确定的情况下直接写入即可, 因此独立写入比较明确;
  4. 链接一有数据尽快读取。这点比较困难,因为读取的数据来自client, client何时写是不确定的, server端需要有一种感知机制;

三、线程池+同步阻塞IO

在这里插入图片描述

  1. 一般由一个线程负责accept新的connection, 而后给每个connection在server端对应一个处理的Thread;
  2. 由于connection会断开, 而Thread创建成本较高, 因此可以使用ThreadPool来管理;
  3. 数据接收通过SocketInputStream完成; 没有数据时, 线程处于block状态;
  4. 数据发送通过SocketOutputStream完成;
  5. 连接数受线程数限制, 因此支持的链接数非常有限。但由于实现简单, 如果并发连接数可控比如20个上限也可以考虑(比如一些技术验证); 此外, 如果发送的消息比较大(M级别), 由于存在多次复制, 数据发送延迟也会比较明显。

到这里, 想必你已意识到网络应用中server端的三大块–连接管理, IO管理和应用逻辑。而IO管理和应用逻辑对资源的消耗与连接数呈正相关。一请求一线程模式, 随着链接数的上升CPU占用直线上升, 这就是著名的C10K问题。业界认为过多的线程切换, 数据的多次复制均需要CPU参与最终导致了这一结果。于是就有了下面的改进方案。

四、reactor模式

  1. 数据读取开始前, 先由一个线程(称为reactor)获取链接的ready标记;
  2. 仅对存在数据的链接读取数据, 数据读取完成后作为一个事件放入一个事件队列(称为EventQueue)中;
  3. 创建一个处理线程(EventLoop)循环读取事件队列中的而后处理;
  4. 数据写入时也放入队列中, 由处理线程读取并发送;
  5. 相比于一请求一线程模式, reactor模式可以使用更少的线程, 节约了CPU的调度时间。此外, IO方式需要增加对ready标记读取支持, 这就是同步非阻塞IO。试想如果数据已经ready, 则意味着内核已经完成数据读取, 只是等待应用发起拷贝而已。因此, 实际的读取过程依然是内存复制完成, 用户线程依然是阻塞的。
  6. Netty对此做了优化, 做到应用内存与内核共享部分堆外内存, 减少了内核到应用的一次拷贝, 进一步提升性能。以下是reactor模式的几种实现, 本质上是对Reactor线程和EventLoop线程的组合。

1. 单reactor+单 EventLoop

在这里插入图片描述

2. 单reactor+N EventLoop

在这里插入图片描述

3. (单reactor+N EventLoop) * N

在这里插入图片描述

总结

以上就是今天要讲的内容,本文介绍了Java网络应用中的几种IO模型,后续会追更Proactor模式以及AIO相关内容,希望能于在读的你能更好理解IO模型,于我个人能做进一步的整理和总结。

相关文章:

I/O模型

写在前面 前面聊完了IO方式, 也就意味着网络数据的收发通道是建立起来了。但业务场景中, 通道本身是不会发送数据的。在常见的网络应用中, server端会创建多个链接以服务更多client, 同时要求各个client尽可能互不影响。这是I/O模型(也就是IO方式线程模型)要解决的问题。由于加…...

前端必备技术之——AJAX

简介 AJAX 全称为 Asynchronous JavaScript And XML,就是异步的 JS 和 XML(现在已经基本被json取代)。通过 AJAX 可以在浏览器中向服务器发送异步请求,最大的优势:无刷新获取数据。AJAX 不是新的编程语言,而是一种将现有的标准组…...

MySQL数据库 各种指令操作大杂烩(DML增删改、DQL查询、SQL...)

文章目录前言一、DML 增删改添加数据修改数据删除数据二、DQL 查询基本查询条件查询聚合函数(count、max、min、avg、sum)分组查询(group by)排序查询(order by)分页查询(limit)DQL 语句练习三、SQLDCL 权限控制约束案例多表查询事务存储引擎字符串函数数值函数日期函数流程函数…...

Java分布式全局ID(一)

随着互联网的不断发展,互联网企业的业务在飞速变化,推动着系统架构也在不断地发生变化。 如今微服务技术越来越成熟,很多企业都采用微服务架构来支撑内部及对外的业务,尤其是在高 并发大流量的电商业务场景下,微服务…...

算法分析与设计之并查集详解

算法分析与设计之并查集1.前言2.并查集的基础2.1.关于动态连通性2.2.动态连通性的应用场景:2.3.对问题建模:2.4.建模思路:2.5.API2.7.Quick-Find算法:2.8.Quick-Union算法:3. 并查集的应用1.前言 本文主要介绍解决动态…...

Linux - 内存性能评估

文章目录概述free 命令指定的时间段内不间断地监控内存的使用情况通过watch与free相结合动态监控内存状况vmstat命令监控内存“sar –r”命令组合小结概述 内存的管理和优化是系统性能优化的一个重要部分,内存资源的充足与否直接影响应用系统的使用性能。在进行内存…...

00后初中辍学,转行程序员后,终于找到了女朋友

大家好,这里是程序员晚枫,今天继续分享我们的读者投稿,如需投稿赚稿费的朋友,请在后台私信我:投稿。下面我们进入正文吧~ 我是一位 00 后,从初一辍学,到目前为止已有 8 年的时间了,在…...

“Vue学习注意事项:掌握核心特性,注意性能优化和第三方库的使用“

Vue是一款易学易用的JavaScript框架,它可以帮助开发者构建动态、高性能的用户界面。Vue的核心概念包括数据绑定、指令、计算属性和组件化,学习Vue需要注意以下几个点:1. 理解Vue的基本概念和用法Vue的基本概念包括模板、组件、数据绑定、计算…...

计算机网络协议详解(二)

文章目录🔥HTTP协议介绍🔥HTTP协议特点🔥HTTP协议发展和版本🔥HTTP协议中URI、URL、URN🔥HTTP协议的请求分析🔥HTTP协议的响应分析🔥MIME类型🔥HTTP协议介绍 HTTP协议介绍 什么是超…...

【CSS】CSS 复合选择器 ② ( 子元素选择器 | 交集选择器 )

文章目录一、子元素选择器1、语法说明2、代码分析3、代码示例二、交集选择器1、语法说明2、代码示例一、子元素选择器 1、语法说明 子元素选择器 可以选择 某个基础选择器 选择出的 元素组 的 直接子元素 ( 亲儿子元素 ) 中 使用基础选择器 选择 元素 ; 子元素选择器语法 : 父选…...

Java集合专题

文章目录框架体系CollectionListArrayListLinkedListVectorSetHashSetLinkedHashSetTreeSetMapHashMapHashtableLinkedHashMapTreeMapPropertiesCollections框架体系 1、集合主要分了两组(单列集合,双列集合) 2、Collection接口有两个重要的子…...

双重差分法(DID):算法策略效果评估的利器

文章目录算法评估DID原理简单实例Python实现算法评估 作为一名算法出身的人,曾长期热衷于算法本身的设计和优化。至于算法的效果评估,通常使用公开数据集做测试,然后对比当前已公开的结果,便可得到结论。 但是在实际落地过程中&…...

【pytorch】使用mixup技术扩充数据集进行训练

目录1.mixup技术简介2.pytorch实现代码,以图片分类为例1.mixup技术简介 mixup是一种数据增强技术,它可以通过将多组不同数据集的样本进行线性组合,生成新的样本,从而扩充数据集。mixup的核心原理是将两个不同的图片按照一定的比例…...

面向对象设计模式:创建型模式之单例模式

1. 单例模式,Singleton Pattern 1.1 Definition 定义 单例模式是确保类有且仅有一个实例的创建型模式,其提供了获取类唯一实例(全局指针)的方法。 单例模式类提供了一种访问其唯一的对象的方式,可以直接访问&#xf…...

IsADirectoryError: [Errno 21] Is a directory: ‘.‘

项目场景: 基于YOLOv5的室内场景识别 工具:colab 问题描述 Traceback (most recent call last): File “train.py”, line 630, in main(opt) File “train.py”, line 494, in main d torch.load(last, map_location‘cpu’)[‘opt’] File “/usr/…...

判断三角面片与空间中球体是否相交

文章目录一、问题描述二、解题思路​ 在做项目时遇到了一个数学问题,即,如何判断给定一个三角面片与空间中某个球体有相交部分?这个问题看似简单,实际处理起来需要一些方法和手段。一、问题描述 已知空间中球体的球心位置center&a…...

继承下的缺省参数值和访问说明符

前言 本文将介绍 C 继承体系下,函数缺省参数的绑定和函数访问说明符的绑定。这些奇怪的问题实际上不应在我们的代码中出现,但它们能帮助我们理解 C 的动态绑定和静态绑定,也能帮助我们更好的通过面试。 缺省参数值 先来看一段代码&#xf…...

Spring核心模块—— BeanFactoryPostProcessorBeanPostProcessor(后处理器)

后置处理器前言Spring的后处理器BeanFactoryPostProcessor(工厂后处理器)执行节点作用基本信息经典场景子接口——BeanDefinitiRegistryPostProcessor基本介绍用途具体原理例子——注册BeanDefinition使用Spring的BeanFactoryPostProcessor扩展点完成自定…...

产品新人如何培养产品思维?

什么是产品思维?其实很难定义,不同人有不同的定义。有的人定义为以用户为中心打磨一个完美体验的产品;有的定义为从需求调研到需求上线各个步骤需要思考的点,等等。本文想讨论的产品思维是:怎么去发现问题,…...

「兔了个兔」CSS如此之美,看我如何实现可爱兔兔LOADING页面(万字详解附源码)

💂作者简介: THUNDER王,一名热爱财税和SAP ABAP编程以及热爱分享的博主。目前于江西师范大学会计学专业大二本科在读,同时任汉硕云(广东)科技有限公司ABAP开发顾问。在学习工作中,我通常使用偏后…...

零门槛NAS搭建:WinNAS如何让普通电脑秒变私有云?

一、核心优势:专为Windows用户设计的极简NAS WinNAS由深圳耘想存储科技开发,是一款收费低廉但功能全面的Windows NAS工具,主打“无学习成本部署” 。与其他NAS软件相比,其优势在于: 无需硬件改造:将任意W…...

visual studio 2022更改主题为深色

visual studio 2022更改主题为深色 点击visual studio 上方的 工具-> 选项 在选项窗口中,选择 环境 -> 常规 ,将其中的颜色主题改成深色 点击确定,更改完成...

汇编常见指令

汇编常见指令 一、数据传送指令 指令功能示例说明MOV数据传送MOV EAX, 10将立即数 10 送入 EAXMOV [EBX], EAX将 EAX 值存入 EBX 指向的内存LEA加载有效地址LEA EAX, [EBX4]将 EBX4 的地址存入 EAX(不访问内存)XCHG交换数据XCHG EAX, EBX交换 EAX 和 EB…...

在WSL2的Ubuntu镜像中安装Docker

Docker官网链接: https://docs.docker.com/engine/install/ubuntu/ 1、运行以下命令卸载所有冲突的软件包: for pkg in docker.io docker-doc docker-compose docker-compose-v2 podman-docker containerd runc; do sudo apt-get remove $pkg; done2、设置Docker…...

Device Mapper 机制

Device Mapper 机制详解 Device Mapper(简称 DM)是 Linux 内核中的一套通用块设备映射框架,为 LVM、加密磁盘、RAID 等提供底层支持。本文将详细介绍 Device Mapper 的原理、实现、内核配置、常用工具、操作测试流程,并配以详细的…...

Python 包管理器 uv 介绍

Python 包管理器 uv 全面介绍 uv 是由 Astral(热门工具 Ruff 的开发者)推出的下一代高性能 Python 包管理器和构建工具,用 Rust 编写。它旨在解决传统工具(如 pip、virtualenv、pip-tools)的性能瓶颈,同时…...

深入浅出深度学习基础:从感知机到全连接神经网络的核心原理与应用

文章目录 前言一、感知机 (Perceptron)1.1 基础介绍1.1.1 感知机是什么?1.1.2 感知机的工作原理 1.2 感知机的简单应用:基本逻辑门1.2.1 逻辑与 (Logic AND)1.2.2 逻辑或 (Logic OR)1.2.3 逻辑与非 (Logic NAND) 1.3 感知机的实现1.3.1 简单实现 (基于阈…...

c++第七天 继承与派生2

这一篇文章主要内容是 派生类构造函数与析构函数 在派生类中重写基类成员 以及多继承 第一部分:派生类构造函数与析构函数 当创建一个派生类对象时,基类成员是如何初始化的? 1.当派生类对象创建的时候,基类成员的初始化顺序 …...

LOOI机器人的技术实现解析:从手势识别到边缘检测

LOOI机器人作为一款创新的AI硬件产品,通过将智能手机转变为具有情感交互能力的桌面机器人,展示了前沿AI技术与传统硬件设计的完美结合。作为AI与玩具领域的专家,我将全面解析LOOI的技术实现架构,特别是其手势识别、物体识别和环境…...

MySQL的pymysql操作

本章是MySQL的最后一章,MySQL到此完结,下一站Hadoop!!! 这章很简单,完整代码在最后,详细讲解之前python课程里面也有,感兴趣的可以往前找一下 一、查询操作 我们需要打开pycharm …...