后端开发—一文详解网络IO模型

一文看懂Redis 6.0多线程IO 使用I/O线程实现网络I/O多线程化,I/O线程只负责网络I/O和命令解析,不执行具体的命令。Redis的多线程网络模型实际上并不是一个标准的模型,Redis的多线程方案中,I/O线程任务仅仅是通过socket读取客户端请求命令并解析,却没有真正去执行命令。所有客户端命令最后还需要回到主线程去执行,因此对多核的利用率并不算高,而且每次主线程都必须在分配完任务之后忙轮询等待所有I/O线程完成任务之后才能继续执行其他逻辑。Redis目前的多线程方案更像是一个折中的选择。... 阅读详情

网络IO:

网络IO会涉及到两个系统对象 一个是 用户空间 调用 IO 的进程或者线程,另一个是 内核

空间的 内核系统, 比如 发生 IO 操作 read 时,它会经历两个阶段

1. 等待数据准备就绪

2. 将数据 从内核拷贝到进程 或者线程 中。

服务器模型 Reactor 与 Proactor

   对高并发编程网络连接上的消息处理,可以分为两个阶段:等待消息准备好、消息 处理。当使用默认的阻塞套接字时(例如上面提到的 1 个线程捆绑处理 1 个连接),往往是把这两个阶段合而为一,这样操作套接字的代码所在的线程就得睡眠来等待消息准备好,这导致了高并发下线程会频繁的睡眠、唤醒,从而影响了 CPU 的使用效率。高并发编程方法当然就是把两个阶段分开处理。即,等待消息准备好的代码段,与处理消息的代码段是分离的。当然,这也要求套接字必须是非阻塞的,否则,处理消息的代码段很容易导致条件不满足时,所在线程又进入了睡眠等待阶段。那 么问题来了,等待消息准备好这个阶段怎么实现?它毕竟还是等待,这意味着线程还是要睡眠的!解决办法就是,线程主动查询,或者让 1 个线程为所有连接而等待!这就是 IO 多路复用了。多路复用就是处理  等待消息准备好这件事的,但它可以同时处理多个连接!它也可能 等待 ””,所以它也会导致线程睡眠,然而这不要紧,因为它一对多、它可以监控所有连接。这样,当我们的线程被唤醒执行时,就一定是有一些连接准备好被我们的代码执行了。

作为一个高性能服务器程序通常需要考虑处理三类事件: I/O 事件,定时事件及信号。两种 高效 的事件处理模型: Reactor 和 Proactor。

Reactor模型

​Reactor 释义 反应堆 ””,是一种事件驱动机制。和普通函数调用的不同之处在于:应用程序不是主动的调用某个 API 完成处理,而是恰恰相反, Reactor 逆置了事件处理流程,应用程序需要提供相应的接口并注册到 Reactor 上,如果相应的时间发生, Reactor 将主动调用应用程序注册的接口,这些接口又称为 回调函数 。

Reactor 模式是处理并发I/O 比较常见的一种模式,用于同步I/O,中心思想是将所有要处理的I/O 事件注册到一个中心I/O 多路复用器上,同时主线程/进程阻塞在多路复用器上;一旦有I/O 事件到来或是准备就绪(文件描述符或socket 可读、写),多路复用器返回并将事先注册的相应I/O 事件分发到对应的处理器中。

Reactor 模型有三个重要的组件:

多路复用器:由操作系统提供,在linux 上一般是select, poll, epoll 等系统调用。

事件分发器:将多路复用器中返回的就绪事件分到对应的处理函数中。

事件处理器:负责处理特定事件的处理函数。

具体流程如下:

注册读就绪事件和相应的事件处理器;

事件分离器等待事件;

事件到来,激活分离器,分离器调用事件对应的处理器;

事件处理器完成实际的读操作,处理读到的数据,注册新的事件,然后返还控制权;

Reactor 模式是编写高性能网络服务器的必备技术之一,它具有如下的优点:

响应快;编程相对简单,可以最大程度的避免复杂的多线程及同步问题,并且 避免了多线程进程的切换开销可扩展性,可以方便的通过增加 Reactor 实例个数来充分利用 CPU 资源;可复用性, reactor 框架本身与具体事件处理逻辑无关,具有很高的复用性;

实际Reactor 模型可能是这样:

具体流程如下:

处理器发起异步操作,并关注I/O 完成事件

事件分离器等待操作完成事件

分离器等待过程中,内核并行执行实际的I/O 操作,并将结果数据存入用户自定义缓冲区,最后通知事件分离器读操作完成I/O 完成后,通过事件分离器呼唤处理器事件处理器处理用户自定义缓冲区中的数据

  我们可以发现proactor 模型最大的特点就是Proactor 最大的特点是使用异步I/O。所有的I/O 操作都交由系统提供的异步I/O 接口去执行。工作线程仅仅负责业务逻辑。在Proactor 中,用户函数启动一个异步的文件操作。同时将这个操作注册到多路复用器上。多路复用器并不关心文件是否可读或可写而是关心这个异步读操作是否完成。异步操作是操作系统完成,用户程序不需要关心。多路复用器等待直到有完成通知到来。当操作系统完成了读文件操作——将读到的数据复制到了用户先前提供的缓冲区之后,通知多路作系统完成了读文件操作——将读到的数据复制到了用户先前提供的缓冲区之后,通知多路复用器相关操作已完成。多路复用器再调用相应的处理程序,处理数据。

    Proactor 增加了编程的复杂度,但给工作线程带来了更高的效率。Proactor 可以在系统态将读写优化,利用I/O 并行能力,提供一个高性能单线程模型。在windows 上,由于没有epoll 这样的机制,因此提供了IOCP 来支持高并发, 由于操作系统做了较好的优化,windows 较常采用Proactor 的模型利用完成端口来实现服务器。在linux 上,在2.6 内核出现了aio 接口,但aio 实际效果并不理想,它的出现,主要是解决poll 性能不佳的问题,但实际上经过测试,epoll 的性能高于poll+aio,并且aio 不能处理accept,因此linux 主要还是以Reactor 模型为主。

Libevent libev libuv

libevent

名气最大,应用最广泛,历史悠久的跨平台事件库;

libev :

较较libevent而言,设计更简练,性能更好,但对而言,设计更简练,性能更好,但对Windows支持不够好

libuv :

开发nodenode的过程中需要一个跨平台的事件库,他们首选了的过程中需要一个跨平台的事件库,他们首选了libev,但又要支持Windows,故重新封装了一套,linux下用libev实现,Windows下用IOCP实现;

总结:

  掌握了Reactor原理,为以后学习其他网络框架底层代码,打下了基础。

技术参考

  C/C++Linux服务器开发/C++后台开发架构师-学习视频

内容包括C++工程化、高性能及分布式、深入浅出。性能调优、TCP,协程,Nginx源码分析Nginx,ZeroMQ,MySQL,Redis,MongoDB,ZK,Linux内核,P2P,K8S,Docker,TCP/IP,协程,DPDK多个高级知识点。

​

linux网络编程—7层网络以及5种Linux IO模型以及相应IO基础 一、七层网络模型   OSI是Open System Interconnection的缩写,意为开放式系统互联。国际标准化组织(ISO)制定了OSI模型,该模型定义了不同计算机互联的标准,它是一个七层的、抽象的模型体。 文章相关视频讲解: 详解网络编程细节点击:90分钟详解网络编程相关的细节处理 详解底层网络IO模型点击: 底层网络IO模型,必须要懂得10种模型 腾讯认证T9后端开发岗位,linux服务器开发高级架构师系统学习视频点击:C/C++Linux服务器开发高级架构师/Linux后 阅读详情

相关推荐

IO流程解析与基本原理

希望对学习块设备的同学有帮助了通过/proc/devices 能够看到这个块设备驱动注册了. kobject_add在sys/block/下面建立文件

网络IO以及socket编程

再回头来看socket技术,我们大概知道了socket是基于TCP/IP上的通信技术,可是它到底位于网络模型的哪个位置(或哪一层)?可靠传输的目的是我们要尽可能地让接收方接收到发送方发送的数据,因此我们需要向发送方回复确认信息,或者说接收方进行检查。关于流式传输,举一个例子,发送方发送“hello”,数据回像水流一样传输过去,即h,e,l,l,o会依次发送到接收方。:当一个IO操作(如read或write)被调用时,如果操作不能立即完成,调用线程将被阻塞,直到操作完成。当IO操作完成时,程序会收到通知。

2403_85810926的博客 2121

客户/服务器系统中减少网络I/O的方法* (2002年)

客户/服务器的应用逻辑设计是否合理,直接影响到客户/服务器方式应用系统的处理性能。该文以Oracle 8服务器平台为例,提出了通过合理划分的应用逻辑,以提高客户/服务器系统处理性能的方法。

网络IO模型

网络IO: 网络IO会涉及到两个系统对象 一个是 用户空间 调用 IO 的进程或者线程,另一个是 内核 空间的 内核系统, 比如 发生 IO 操作 read 时,它会经历两个阶段 1. 等待数据准备就绪 2. 将数据 从内核拷贝到进程 或者线程 中。 服务器模型 Reactor 与 Proactor   对高并发编程网络连接上的消息处理,可以分为两个阶段:等待消息准备好、消息 ...

347

二阶FLL辅助三阶PLL环路的代码解读

今天对GNSS接收机里面的载波跟踪环路代码进行了解读 以下是个人的一点见解 % 载波环第二步:环路滤波器 二阶FLL辅助三阶PLL环路 carrLoopS0 = lastCarrLoopS0 + (phaseErr*tau0PLL + freqErr*tau1FLL) * PDIcarr; carrLoopS1 = lastCarrLoopS1 + (tau1PLL*phaseErr + carrLoopS0 + tau2FLL*freqErr) * PD

LWN7321的博客 2632

手把手教你用UM982搭建厘米级RTK定位系统(附避坑指南)

本文详细介绍了如何使用UM982模组搭建厘米级RTK定位系统,涵盖硬件连接、软件配置和深度优化技巧。UM982支持BDS、GPS、GLONASS和Galileo等多系统全频点信号,特别适合精准农业、无人机导航等高精度应用场景。通过实战案例和避坑指南,帮助开发者快速实现厘米级定位精度。

y7z8a的博客 1441

【Linux 网络】高级 IO -- 详解

Reactor反应器模式,也被称为分发者模式或通知者模式,是一种将就绪事件派发给对应服务处理程序的事件设计模式。基于多路转接方案,当事件就绪的时候,采用回调的方式,进行业务处理的模式就被称为反应堆模式(Reactor)。上述代码中的 TcpServer 就是一个反应堆,其中一个个 Connection 对象就称为事件。文件描述符独立的缓冲区回调方法回指向反应堆的指针反应堆中有一个事件派发函数,当epoll中的某个事件就绪,事件派发函数回调用此事件的回调函数。

Elena's Blog 2471

Arduino+L298N电机驱动模块避坑指南:从接线到PWM调速的5个常见错误

本文详细解析了使用Arduino与L298N电机驱动模块时,从电源配置、跳线帽使用到PWM调速的5个常见错误与避坑指南。重点阐述了如何正确分离逻辑与电机电源、拔掉ENA/ENB跳线帽以实现PWM调速、理解H桥接线逻辑以控制直流电机正反转,并提供优化代码与散热建议,帮助开发者稳定驱动电机。

rust6ferris的博客 564

后端开发学习日志(IO流篇)

新手学习Java,欢迎大佬们指出错误

Xiaoxian____的博客 2348

Python结合海康威视工业相机SDK实现高效图像采集与处理

本文详细介绍了如何使用Python结合海康威视工业相机SDK实现高效的图像采集与处理。内容涵盖从环境搭建、SDK核心模块理解,到完整的图像采集流程拆解,包括设备枚举、参数设置、主动取流以及关键的像素格式转换。同时,文章深入探讨了触发模式、参数控制等高级应用,并提供了性能优化建议和可复用的相机操作类封装,帮助开发者快速构建稳定的机器视觉应用。

weixin_29043895的博客 350

基于STM32控制直流电机加减速正反转仿真设计

*单片机设计介绍,基于STM32控制直流电机加减速正反转仿真设计。

2201_75940997的博客 1604

彻底搞懂 IO 底层原理

武侠小说里有很多的“心法”和“招式”。计算机技术里的“心法”和“招式”呢,我们可以简称为“道”和“术”; “道”最基础的计算机理论,隐藏于表象之下,非常抽象、晦涩难懂,需要用具象化的事物加以理解; “术”具体的技艺,它有可能是一门语言,比如:python 出手见效快; 我们今天要给大家讲的底层的IO就属于“道”的范畴,看上去简单,实则抽象。并且在它之上衍生出了语言层面用于实战的技术,比如我们熟悉的java语言中的NIO或者像Netty这样的框架。 一、混乱的 IO 概念 IO是Input...

vivo互联网技术 2456

1991-2020年气候背景数据集

2011 年,国家气象信息中心对 1951-2010 年 2400 余个地面站气温、气压、降水、湿度、日照等 19 大要素项的定时观测资料和日极值资料中由数字化过程中引起的系统性问题(例如数字化遗漏、整段拷贝等问题)进行质量检测、质量控制和错误数据的更正,形成较高质量的地面基础资料集。1991-2020年中国地面气候值数据集提供了中国2438个站点的气温、降水、气压、风向风速、相对湿度、水汽压、云、天气现象、能见度、蒸发、积雪、地温、冻土、日照共14个要素的气候背景信息。数据时间:30年平均。

地球资源数据云的官方博客 1598

后端开发核心技术 第7章网络IO模型 4种网络IO模型

IO两种操作 同步IO 必须等待IO操作完成后,控制权才给用户进程 异步IO 无须等待IO 完成操作,就将控制权给用户进程 网络中IO常见4种情况 输入操作:等待数据达到套接字接收缓冲区 输出操作:等待套接字发送缓冲区有足够的空间容纳将要发送的数据 服务器接受连接请求:等待新的客户端连接请求的到来 客户端发送连接请求:等待服务器回送客户发起的SYN对应的ACK 4种网络IO模型 阻塞IO模型 非阻塞IO模型 多路IO复用模型 异步IO模型 ...

weixin_43095021的博客 248

1、Ka频段双极化低剖面卫通相控阵天线

设计了双馈口叠层十字缝隙耦合天线,采用“双线极化天线 +旋转馈电 + 移相控制”架构,采用双馈口的叠层十字缝隙耦合天线,并以 2 x2 阵列为主体,旋转排布实现二次圆极化,同时极化可切换,通过多层 PCB 工艺实现天线层、控制/电源层功分网终层、芯片层一体化集成,研制出 64 阵元的圆极化可切换发射天线,测试结果表明:天线工作 频段为 27.5 ~31 GHz,可实现60°扫描,法向轴比

qq_43416206的博客 4371

基于Simulink的伺服电机位置闭环控制仿真

本文带你从零构建了伺服电机位置闭环控制系统​ 的完整Simulink仿真模型,实现了:✅ 搭建PMSM伺服电机、逆变器、机械臂负载的主电路与编码器反馈模型;✅ 用MATLAB Function实现三环控制(位置环PID、坐标变换、电流环PI);✅ 验证阶跃定位(稳态误差0.002°、响应0.08s)与正弦跟踪(误差0.008°)的高性能;✅ 对比开环控制,明确位置闭环在精度、响应、抗扰上的优势;✅ 理解“三环嵌套+反馈校正”的核心思想(精密定位的工程实现)。核心收获。

amy_mhd的博客 173

后端开发工程师必须知道的Linux 网络IO模型

Linux网络IO模型同步和异步,阻塞和非阻塞五种I/O模型阻塞I/O模型非阻塞IO模型IO复用模型信号驱动IO(了解)异步IO模型(了解)五个I/O模型的比较select、poll、epoll的区别 同步和异步,阻塞和非阻塞 同步和异步 请求方是否需要等待结果返回。 同步:请求方需要主动等待结果的返回 异步:不需要主动等待结果的返回,而是通过其他手段比如,状态通知,回调函数等。 阻塞和非阻塞 ...

日有寸进 528

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

后端开发【一大波有用知识】网络通信模型和网络IO管理

简单的C/S通信模型(accept阻塞的话,就只能一个客户端接进来) socket()函数 //函数原型。返回:若是成功则为非负数,如出错则为 -1 int socket(int domin, int type, int protocol); //调用 参数1:使用多少位地址AF_INET 为32,参数2:数据报的类型。 参数3:TCP/UDP 协议 int clientfd = socket(AF_INET, SOCK_STREAM, 0); connect() 函数,用来向服务器建立

Linuxhus的博客 263

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

ssm框架搭建

这个是一个在idea上成功跑起来的ssm框架项目,保存在这里方便以后使用直接下载

C++后端开发(2.1.1)——网络io模型中的阻塞与非阻塞

C++后端开发(2.1.1)——网络io模型中的阻塞与非阻塞0.简介1.基本代码框架2.阻塞——单线程3.阻塞——多线程2.多路复用——select3 多路复用——poll3.1 pollfd结构体3.2 poll使用实例3.3 poll执行流程3.4 对于select提升的地方3.5 poll弊端4.多路复用——epoll4.1 epoll 所使用的函数与解析4.1.1 参数解析4.2 epoll 关键结构体epoll_event *event4.3 epoll优点4.3 epoll 使用实例 本节提纲

weixin_43687811的博客 1840

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

五种网络IO模型详解

一 IO操作本质 数据复制的过程中不会消耗CPU # 1 内存分为内核缓冲区和用户缓冲区 # 2 用户的应用程序不能直接操作内核缓冲区,需要将数据从内核拷贝到用户才能使用 # 3 而IO操作、网络请求加载到内存的数据一开始是放在内核缓冲区的 文章相关视频讲解: C/C++ Linux服务器开发高级架构学习视频点击:C/C++Linux服务器开发高级架构/Linux后台架构师-学习视频 90分钟搞定底层网络IO模型,必须要懂得10种模型 epoll原理剖析以及reactor模型应用 .

Linuxhus的博客 402

【Linux网络】深入理解五种IO模型与非阻塞IO:从本质到实战

做后端开发的朋友们应该都有一个共识:绝大多数服务的性能瓶颈,最终都会落到 IO 上。无论是网络请求的收发、磁盘文件的读写,还是数据库的交互,本质上都是在处理 IO 操作。很多人写代码时只会用默认的阻塞 IO,遇到高并发就只会无脑加线程,结果线程越开越多,上下文切换的开销反而拖垮了整个系统。其实问题的根源在于没有真正理解 IO 的本质,也不知道操作系统提供了哪些更高效的 IO 模型。本文将从最底层的 IO 本质讲起,用大家都能听懂的 “钓鱼” 类比,带你彻底搞懂 Linux 下的五种 IO 模型,最后通过实战

会当凌绝顶,一览众山小 7741

后端服务器网络编程之 IO 模型

基本概念   在编写服务器端网络程序时,我们最常见到阻塞、非阻塞、同步和异步这四个词。它们的解释分别如下: 阻塞: 阻塞调用是指调用返回之前,当前线程会被挂起,只有当调用得到结果后才返回。 非阻塞:与阻塞相反,非阻塞调用是指在不能立即得到结果之前,该函数不会将当前线程阻塞,而是立即返回。 同步:所谓同步,就是在发出一个功能调用时,在没有得到结果之前,该调用就不返回。等前一件做完了才能做下一件事。 异步:异步的概念和同步相对。当一个异步过程调用发出后,调用者不能立刻得到结

Linuxhus的博客 295

从网络IO看高性能框架

前言: 我是一名golang后端开发工程师,不是Java,也不是拍黄片,对,就是那个号称原生支持高并发的“够浪!”。那为什么go能支持高并发?原生支持高并发又是何解?跟着我,一起探讨一下所谓的高并发是怎么回事… 阅读本文你将收获: 知道框架高性能的根本原因 了解进程,线程切换开销在哪里 熟悉阻塞与非阻塞IO,同步与异步调用的区别 大纲: 讨论一个高性能框架甚至语言的时候,我们在讨论什么? 三...

firstresponder的专栏 799

深入理解IO模型:阻塞IO、非阻塞IO与IO多路复用

阻塞IO(Blocking I/O),顾名思义,是指在进行IO操作时,如果数据尚未准备好,发起IO请求的线程会被阻塞,直到数据准备完成并拷贝到用户空间。在BIO模型中,通常采用“一个连接一个线程”的处理方式。非阻塞IO(Non-blocking I/O)是指在进行IO操作时,如果数据尚未准备好,IO调用会立即返回,不会阻塞当前线程。线程可以继续执行其他任务,并通过轮询机制(或Selector通知)判断数据是否准备就绪。在NIO模型中,通常采用“一个线程处理多个连接”的方式。

weixin_56018532的博客 1577

后台开发看过来:这次带你一举拿下网络IO模型

IO 是计算机体系中重要的一部分 。不同的 IO 设备有着不同的特点:数据率不一样、传送单位不一样,数据表示不一样,等等。所以,很难实现一种统一的输入输出方法。

Javatutouhouduan的博客 624

图文详解Linux的IO模型和相关技术

阻塞IO模型(Blocking I/O) Linux内核一开始提供了read与write阻塞式操作。 当客户端连接时,会在对应进程的文件描述符目录(/proc/进程号/fd)生成对应的文件描述符(0 标准输入;1 标准输出;2 标准错误输出;),比如 fd 8 , fd 9; 应用程序需要读取的时候,通过系统调用read (fd8)读取,如果数据还没到来,此应用程序的进程或线程会阻塞等待。 man 2 read 概述 #include <unistd.h&g...

Linuxhus的博客 242
上一篇: 设计模式—代理模式以及动态代理的实现
下一篇: Linux环境,C/C++语言手写代码实现线程池
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值