详细介绍BIO、NIO、IO多路复用(select、poll、epoll)

news2024/9/20 1:00:07

BIO、NIO、IO多路复用

  • BIO(Blocking IO)
  • NIO(Non-blocking IO) 同步非阻塞IO
  • IO多路复用
    • select
    • poll
    • epoll
  • Redis的IO多路复用

BIO(Blocking IO)

最基础的IO模型,当进行IO操作时,线程会被阻塞,直到操作完成。
比如read和write,通常IO操作都是阻塞I/O的,也就是说当你调用read时,如果没有数据收到,那么线程或者进程就会被挂起,直到收到数据。无法处理并发。
阻塞 I/O 是最简单的 I/O 模型,一般表现为进程或线程等待某个条件,如果条件不满足,则一直等下去。条件满足,则进行下一步操作。
在这里插入图片描述

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

  • 在这种模型中,线程可以在不阻塞的情况下对文件描述符进行读写操作。
  • 当你调用read时,如果有数据收到,就返回数据,如果没有数据收到,就立刻返回一个错误(标识符),这样是不会阻塞线程了。此时用户进程需要不断轮询,如果轮询频繁,则浪费了大量的CPU资源;如果轮询频率低,则不能实时地获取数据。
    不断轮询,过度浪费CPU资源。
    在这里插入图片描述

IO多路复用

  • 文件描述符:简称fd,是一个从0开始递增的无符号整数,用来关联Linux中的文件,在Linux中,一切皆文件,例如常规文件、视频,也包括网络套接字
  • IO多路复用:利用单个线程可以监视并同时等待多个文件描述符,而不是使用多个线程(每个文件描述符一个线程,每次new一个线程),当这些文件描述符(套接字描述符)其中一个进入读就绪或者写就绪,select、poll、epoll就可以返回,从而避免无效的等待,充分利用CPU资源
    在这里插入图片描述

select

可以看到select监听的文件描述符包括三个readfds、writefds、exceptfds,将用户传入的数组拷贝到内核空间,select会被阻塞,直到描述符就绪,返回。
请添加图片描述
selcet核心执行流程

  • select是一个阻塞函数,当没有数据时,会一直阻塞在select。
  • 当有数据时,会将对应的rset设置为1
  • select函数返回,不在阻塞。遍历文件描述符判断那个fd置位,读取数据,然后处理。

缺点:

  • bitmap 最大1024 一个进程最多处理1024个客户端。
  • rset位不可重复用,每次socket有数据就会相应的位被置位。
  • 文件描述符数组拷贝到了内核态,select调用需要传入fd数组,需要拷贝一份到内核,高并发场景下消耗的资源是惊人的。
  • select没有通知用户态哪一个socket有数据,select仅返回可读文件的个数,具体哪个可读还需要用户自己O(N)遍历。

小结:select方式,既做到了一个线程处理多个客户端连接(文件描述符),又减少了系统调用的开销(多个文件描述符只有一次 select 的系统调用 + N次就绪状态的文件描述符的 read 系统调用

poll

在select类似,在select上做了一部分改进,并没有解决根本问题。
优点

  • 使用数组来解决select的bitmap 1024限制。
  • 有事件发生时,将对应的revents置位位为1,遍历的时候将对应的位置设置为0,可以实现重用。

缺点
本质上还是select方法

  • poll 将fds数组拷贝到内核态,仍然有开销。
  • poll并没有通知用户态那个socket有数据,还是需要O(N)遍历

epoll

  • 会在通知用户进行FD就绪的同时。把已就绪FD写入用户空间,
  • 无需遍历所有FD 多路复用快一次系统调用+内核层遍历这些文件描述符
  • socket生命周期只会从用户态到内核态拷贝一次
  • 使用event通知级值,每次socket有数据会主动通知内核加入就绪列表,不需要遍历所有socket

在这里插入图片描述

Redis的IO多路复用

redis中IO阻塞的问题

Rdis是跑在单线程中的,所有的操作都是按照顺序线性执行的,但是由于读写操作等待用户输入或输出都是阻塞的,所以I/O操作在一般情况下往往不能直接返回,这会导致某一文件的I/O阻塞导致整个进程无法对其它客户提供服务,而I/O多路复用就是为了解决这个问题而出现

Redis使用epoll实现IO多路复用

Redis利用epoll来实现IO多路复用,将连接信息和事件放到队列中,依次放到文件事件分派器,事件分派器将事件分发给事件处理器。
请添加图片描述
Redis服务采用Reactor的方式来实现文件事件处理器(每一个网络连接其实都对应一个文件描述符)
Reactor模式,是指通过一个或多个输入同时传递给服务处理器的服务请求的事件驱动处理模式。服务端程序处理传入多路请求,并将它们同步分派给请求对应的处理线程

Reactor模式
Reactor模式也叫Dispatcher模式。即I/O多了复用统一监听事件,收到事件后分发(Dispatch给某进程),是编写高性能网络服务器的必备技术。Reactor模式中有2个关键组成:

  1. Reactor,Reactor在一个单独的线程中运行,负贵监听和分发事件,分发给适当的处理程序来对IO事件做出反应。它就像公司的电话接线员,它接听来自客户的电话并将线路转移到适当的联系人
  2. Handlers,处理程序执行I/O事件要完成的实际事件,类似于客户想要与之交谈的公司中的实际办理人。Reactor通过调度适当的处理程序来响应I/O事件,处理程序执行非阻塞操作
    请添加图片描述

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

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

相关文章

string indices must be integers

string indices must be integers 目录 string indices must be integers 【常见模块错误】 【解决方案】 常见原因及解决方法 具体案例分析 总结 欢迎来到英杰社区https://bbs.csdn.net/topics/617804998 欢迎来到我的主页,我是博主英杰,211科班出…

python基础---2.流程控制及函数

🎈个人主页:靓仔很忙i 💻B 站主页:👉B站👈 🎉欢迎 👍点赞✍评论⭐收藏 🤗收录专栏:python 🤝希望本文对您有所裨益,如有不足之处&…

Godot入门 07 世界构建2.0

添加基础节点Node,重命名为Coins,整理场景树,拖动Coin到Coins节点下。 添加基础节点Node,重命名为Platforms,整理场景树,拖动Platform到Platforms节点下。 添加游戏背景 设置当前图层名称为Mid 添加图层元…

sql基础查询

1.基础查询语法 distinct去重 例子: 尽量不写* 影响效率

智慧校园行政办公:优化车辆保险费用管理的新选择

在智慧校园的行政办公系统中,车辆保险费用管理功能扮演着不可或缺的角色,它专注于校园内公务用车的保险费用的系统化与自动化管理,旨在提升财务管理的透明度,减少人为失误,优化保险支出。这一功能的核心在于信息的准确…

Javascript面试基础6【每日更新10】

Gulp gulp是前端开发过程中一种基于流的代码构建工具,是自动化项目的构建利器;它不仅能对网站资源进行优化,而且在开发过程中很多重复的任务能够使用正确的工具自动完成 Gulp的核心概念:流 流,简单来说就是建立在面向对象基础上的一种抽象的…

【前端 14】Vue常见指令

Vue常见指令 Vue.js 是一个构建用户界面的渐进式框架,它通过一系列简洁的指令(Directives)来增强HTML的功能,使得开发者能够更加方便地构建出响应式的Web应用。本文将详细讲解Vue中的几个核心指令:v-bind、v-model、v…

[算法题]爱丽丝的人偶(一)

题目链接: 爱丽丝的人偶&#xff08;一&#xff09; 定义两个变量, 分别初始化为 1 和 n, 让两个变量不断向中间聚拢, 并同时按先输出最小值再输出最大值的规律输出, 如图: 这样就满足题意排好了, 题解代码: #include <iostream> using namespace std;int main() {int …

PlantUML学习笔记-嵌入式系统设计常用图例

在嵌入式系统设计过程中&#xff0c;需要使用一些图例对系统框架及业务流程进行说明&#xff0c;以便于多人协同开发及后期的系统维护&#xff0c;提高团队开发效率。 1. 嵌入式设计开发常使用的图例&#xff1a; 1.1 用例图&#xff08;Use Case Diagram&#xff09; 用例图…

美国GE工业大项目中断,一天内市值蒸发近290亿人民币,波及西门子等同行……...

导语 大家好&#xff0c;我是社长&#xff0c;老K。专注分享智能制造和智能仓储物流等内容。 新书《智能物流系统构成与技术实践》 本周二&#xff0c;美国东海岸发生了一起令人瞠目结舌的事件。GE Vernova公司参与的Vineyard Wind海上风电项目的一片巨型涡轮机叶片竟然断裂坠海…

《JavaEE》----2.<多线程的简介创建Thread类>

前言&#xff1a; 大家好&#xff0c;我目前在学习java。我准备利用这个暑假&#xff0c;来复习之前学过的内容&#xff0c;并整理好之前写过的博客进行发布。如果博客中有错误或者没有读懂的地方。热烈欢迎大家在评论区进行讨论&#xff01;&#xff01;&#xff01; 喜欢我文…

Python装饰器:让函数更强大

在Python编程中&#xff0c;装饰器是一个强大的工具&#xff0c;它允许程序员以一种简洁优雅的方式修改或增强函数的行为&#xff0c;而无需更改其源代码。本文将介绍装饰器的基本概念、工作原理以及一些实际应用案例。 什么是装饰器&#xff1f; 装饰器本质上是一个接受函数…

Python酷库之旅-第三方库Pandas(049)

目录 一、用法精讲 176、pandas.Series.rank方法 176-1、语法 176-2、参数 176-3、功能 176-4、返回值 176-5、说明 176-6、用法 176-6-1、数据准备 176-6-2、代码示例 176-6-3、结果输出 177、pandas.Series.sem方法 177-1、语法 177-2、参数 177-3、功能 177…

【C语言】数组名的不同情况

前言 在C语言中&#xff0c;数组名的行为在不同的上下文中有细微的区别。数组名本质上是一个指向数组第一个元素的指针&#xff0c;但在某些情况下&#xff0c;它的行为会有所不同。以下是一些关键点&#xff0c;帮助你理解数组名在什么情况下代表第一个元素&#xff0c;什么情…

前端江湖:从菜鸟到大侠的修炼手册

在这个数字编织的梦幻世界里&#xff0c;前端&#xff0c;这个听起来就带着几分仙气与神秘感的词汇&#xff0c;实则是每一位互联网探险家手中的魔法杖。它不仅连接着代码的冰冷逻辑与用户的炽热情感&#xff0c;更在无数次的点击与滑动间&#xff0c;绘制出一幅幅绚丽多彩的交…

智慧港口整体解决方案

1. 智慧港口概况与建设意义 智慧港口建设对创新驱动和转型发展具有重要推动作用&#xff0c;是港口发展的主要方向。它通过物联网、移动互联网、云计算、人工智能等高新技术与港口功能的融合&#xff0c;提升港口的智能化和信息化水平&#xff0c;对国家可持续发展具有重要意义…

一键将桌面资料存到d盘的工具,小巧、绿色、免费、免安装

为了提升我们的系统稳定性以及资料的安全性&#xff0c;建议大家将电脑桌面的资料默认路径设置为D盘或其他磁盘&#xff0c;这样不仅会减少系统盘的占用空间&#xff0c;在系统盘出现故障时我们还可以通过pe工具备份桌面的资料。虽然我们也可以通过一些操作来修改桌面文件以及我…

视频主题Qinmei 3.0视频站源码_WordPress影视视频主题/附详细安装教程

Qinmei 3.0主题主要是将 wordpress 改造成纯 api 的站点&#xff0c;以便实现前后端分离的技术栈&#xff0c;目前的进度已经大致完成&#xff0c;唯一的问题就是需要安装 JWT token 插件。 功能介绍&#xff1a; 支持豆瓣以及 bangumi 的一键获取信息, 豆瓣 api 目前使用的是…

科普文:分布式架构中的三高:高并发、高性能、高可用

关于高并发 高并发场景 互联网应用以及云计算的普及&#xff0c;使得架构设计和软件技术的关注点从如何实现复杂的业务逻 辑&#xff0c;转变为如何满足大量用户的高并发访问请求。 一个简单的计算处理过程&#xff0c;如果一旦面对大量的用户访问&#xff0c;整个技术挑战就…

Java1.0标准之重要特性及用法实例(十一)

简介&#xff1a; CSDN博客专家&#xff0c;专注Android/Linux系统&#xff0c;分享多mic语音方案、音视频、编解码等技术&#xff0c;与大家一起成长&#xff01; 新书发布&#xff1a;《Android系统多媒体进阶实战》&#x1f680; 优质专栏&#xff1a; Audio工程师进阶系列…