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

Reactor 和 Proactor模式,IO复用与epoll、同步IO,异步IO与协程

汽车软件中的CPU密集与IO密集任务

在汽车软件中,涉及到ADAS的长期占用CPU的计算任务可以算的上是CPU密集型。

另外的,众多SOA原子服务或者各种数据收集、处理、分发、log系统,应该算是IO密集型任务。

寻求一些手段优化IO性能的原因

在过去开发应用或者中间件时,使用Linux提供的接口,例如直接socket,一般就两种模式,实质上是使用了同步IO:

1、开启循环子线程,阻塞在socket接收处。

2、线程开启循环,周期轮询socket。

这种方式造成了一些弊端,例如对每个socket都需要维护一个子线程,系统给每个线程分配资源造成了资源浪费(如内存)。
虽然阻塞不占用CPU时间,但是如果存在大量socket子线程,线程调度会花费很多CPU时间在进程切换中。造成系统CPU负载率高。

潜在的解决方案

经过研究,一些关键词引起关注。正如本文的标题。

Reactor 和 Proactor模式

Reactor模式和Proactor模式都是基于事件驱动的设计模式,用于处理高并发环境下的I/O多路复用问题。然而,它们在处理I/O事件的方式上有所不同。

Reactor模式是非阻塞同步网络模式,它感知的是就绪可读写事件。具体来说,当某个I/O事件(例如可读就绪)发生时,需要应用进程主动调用相应的read方法来完成数据的读取。这个过程是同步的,即读取完数据后应用进程才能处理数据。因此,Reactor模式可以理解为“来了事件操作系统通知应用进程,让应用进程来处理”。

Proactor模式则是异步网络模式,它感知的是已完成的读写事件。在发起异步读写请求时,需要传入数据缓冲区的地址等信息,这样系统内核才可以自动帮我们把数据的读写工作完成。这里的读写工作全程由操作系统来做,并不需要像Reactor那样还需要应用进程主动发起read/write来读写数据。操作系统完成读写工作后,就会通知应用进程直接处理数据。因此,Proactor模式可以理解为“来了事件操作系统来处理,处理完再通知应用进程”。

总的来说,Reactor和Proactor模式都是基于事件分发的网络编程模式,区别在于Reactor模式是基于“待完成”的I/O事件,而Proactor模式则是基于“已完成”的I/O事件。因此,Proactor模式更加高效,因为它避免了线程间的协作,可以更快地响应I/O事件,但是它的实现相对比较复杂。

IO复用

所谓IO复用,目的是解决前述问题中的每个socket开一个线程的问题。

使用IO复用的机制或者进行IO复用设计(如上文的Reactor模式),使用一个进程监听多个socket。

例如使用一个线程监听多个事件源(如socket),当有事件发生或者可读后,通知对应的程序处理。

落实到Linux内核来帮你做,就变成了Linux IO复用机制,以前有select poll。现在是epoll。

epoll 机制与Reactor

epoll

epoll是Linux下的一个I/O多路复用技术,用于高效地处理大量并发连接。它提供了一组接口,用于注册、修改和删除文件描述符的监听事件。

epoll的接口包括以下几个:

  1. epoll_create():创建一个新的epoll实例,并返回一个指向它的文件描述符。
  2. epoll_ctl():注册、修改或删除文件描述符的监听事件。它需要传入epoll实例的文件描述符、文件描述符、事件类型和回调函数。
  3. epoll_wait():等待注册的文件描述符就绪,并返回就绪的文件描述符列表。它需要传入epoll实例的文件描述符和最大等待时间。
  4. epoll_pwait():与epoll_wait类似,但是可以设置超时时间,并且可以同时处理多个事件。

使用epoll的一般步骤如下:

  1. 创建一个epoll实例,获取其文件描述符。
  2. 使用epoll_ctl()函数注册需要监听的事件和回调函数。
  3. 在需要处理事件的时候,调用epoll_wait()或epoll_pwait()函数等待事件的发生。
  4. 处理就绪的事件。

Reactor

Reactor模式是一种事件驱动的设计模式,用于处理高并发环境下的I/O多路复用问题。它由以下几个组件组成:

  1. Reactor(反应器):是一个接口,定义了注册事件处理器、分发事件和事件处理的方法。通常,Reactor通过异步方式将事件分发给注册的事件处理器。
  2. Event Handler(事件处理器):是一个接口,定义了事件的回调方法。事件处理器实现了Reactor接口,并注册自己感兴趣的事件类型。当事件发生时,Reactor调用事件处理器的回调方法来处理事件。
  3. Concrete Event Handler(具体事件处理器):是事件处理器的实现。在其内部实现了事件处理器的回调方法,进行业务逻辑处理。
  4. Initiation Dispatcher(初始分发器):实际上就是Reactor角色。它本身定义了一些规范,这些规范用于控制事件的调度方式。同时又提供了应用进行事件处理器的注册、删除等操作。它本身是整个事件处理器的核心所在,Initiation Dispatcher会通过Synchronous Event Demultiplexer来等待事件的发生。

工作方式:

  1. 应用程序创建Reactor对象,并注册感兴趣的事件类型和对应的事件处理器。
  2. 当事件发生时,Initiation Dispatcher通过Synchronous Event Demultiplexer将事件传递给对应的事件处理器。
  3. 事件处理器接收到事件后,执行相应的业务逻辑处理。
  4. 处理完成后,事件处理器会再次注册自己感兴趣的事件类型,以便后续继续处理事件。

可以看出,epoll是一个近似于reactor的实现,或者说,基于epoll机制,可以比较方便的实现一个reactor模式来实现事件驱动程序设计。

我们需要做的是,在epoll 的wait返回后,根据返回的socket 就绪列表,去分发,去调用对应的处理程序。

相较于异步IO来说,在分发的时候这个socket还没有被读取,需要应用程序去读取,但是在调用读取的系统调用的时候,也会存在一个阻塞读取数据,例如从内核态拷贝到用户态的过程,我觉得这对目前的工作来讲已经过于玄学了,车端的应用没互联网那么夸张。

Proactor模式 异步IO Boost.asio 协程

Proactor模式是一种消息异步通知的设计模式,它主要用于处理高并发环境下的I/O多路复用问题。以下是Proactor模式的各个组件及其功能和工作方式:

  1. Handle句柄:用于标识socket连接或者是打开文件。在网络服务器中,每个客户连接都会创建不同的套接字句柄,当异步连接、读、写操作执行完成时,完成事件会出现在这些句柄上。
  2. Asynchronous Operation Processor(异步操作处理器):负责执行异步操作,一般由操作系统内核实现。
  3. Asynchronous Operation(异步操作):这是应用程序发出的服务请求,比如异步的通过套接字句柄读写数据。当异步操作激活后,操作不需要借用回调线程的控制即可执行。因此从回调者角度看,操作的执行是异步的。
  4. Completion Event Queue(完成事件队列):异步操作完成的结果会放到队列中,等待后续使用。
  5. Proactor(主动器):为应用程序提供事件循环,从完成事件队列中取出异步操作的结果,分别调用相应的后续处理逻辑。
  6. Completion Handler(完成事件接口):一般是由回调函数组成的接口。
  7. Concrete Completion Handler(完成事件处理逻辑):完成接口定义特定的应用处理逻辑。

在业务流程及时序图中,应用程序启动后,会调用异步处理器提供的异步操作接口来发起异步操作。异步操作处理器接收到操作请求后,会执行相应的异步操作。当操作完成后,会将完成事件放入完成事件队列中。Proactor会不断地轮询完成事件队列,一旦发现有完成事件,就会调用相应的回调函数来处理完成事件。

Boost.Asio是一个广泛使用的C++库,用于处理低级网络编程和并发任务。它实现了Proactor模式,提供了一种高效和灵活的方式处理异步I/O操作。

在Boost.Asio中,Proactor模式的应用主要体现在异步I/O操作的处理上。具体来说,当应用程序发起一个异步操作(如异步读或写)时,Boost.Asio会将其封装为一个异步操作对象,并将其注册到异步事件处理器中。

异步事件处理器使用异步事件分发器(Asynchronous Event Demultiplexer)来等待事件完成。当异步操作完成时,完成事件会被放入完成事件队列中。然后,Proactor会调用异步事件分发器,将完成事件返回给其调用者。

在处理完成事件时,Proactor会调用相应的回调函数。

这个回调函数通常是由应用程序通过boost::bind创建的函数对象,用于处理异步操作的结果。

通过这种方式,Boost.Asio实现了高效的异步I/O处理,使得应用程序可以在不阻塞主线程的情况下处理大量的并发连接和请求。同时,Proactor模式还提供了回调函数的方式,使得应用程序可以灵活地处理完成事件,从而实现了异步编程。

据说,底层是epoll。。

异步IO与协程

之前我想过一个问题,异步IO可以在调用IO操作之后先干别的,不用等待。

在同步(按照时间顺序,典型的C编程)方式下,我调用IO,肯定是要IO的数据,如果不等着拿数据,这个时候能干嘛呢。

直到我看到了协程这个东西,豁然开朗(之前也困惑或协程这个在一个进程内跳来跳去执行的东西有什么用)。

协程和异步IO结合,可以进一步优化IO密集任务。

异步IO,实际上就是给各个事件注册处理函数,让程序在各个处理函数之间跳来跳去,就是纯纯用户态的事情了,甚至可以躲在用户进程里不出来,根本没有切换进程开销,岂不美哉。

相关文章:

Reactor 和 Proactor模式,IO复用与epoll、同步IO,异步IO与协程

汽车软件中的CPU密集与IO密集任务 在汽车软件中,涉及到ADAS的长期占用CPU的计算任务可以算的上是CPU密集型。 另外的,众多SOA原子服务或者各种数据收集、处理、分发、log系统,应该算是IO密集型任务。 寻求一些手段优化IO性能的原因 在过去…...

nginx反向代理服务器及负载均衡服务配置

一、正向代理与反向代理 正向代理:是一个位于客户端和原始服务器(oricin server)之间的服务器,为了从原始服务器取得内容,客户端向代理发送一个请求并指定目标(原始服务器),然后代理向原始服务器转交请求并将获得的内容返回给客户…...

【Log4j2】Log4j2最佳实践:Log4j2配置超过7天压缩,超过3个月删除文件的滚动日志,分别定义info文件和error文件,按照每小时存储

目录 Log4j2配置 springboot多环境日志配置 参考资料 Log4j2配置 如果你想要在控制台输出美化的日志信息&#xff0c;你可以使用Log4j2的ConsoleAppender和AnsiColorConverter来实现。下面是相应的配置示例&#xff1a; <Configuration status"WARN"><…...

windows和Linux如何做强制域名解析

首先我们了解两个问题&#xff1a; 一、域名解析是什么&#xff1f; 域名解析是让我们可以通过网站的域名来找到它对应的IP地址&#xff0c;以便更加方便的访问我们所需访问的网站的一种服务。 它通过DNS服务器来进行&#xff0c;我们输入所想要访问的域名&#xff0c;将会通过…...

5G NTN:通信新天地,卫星通信的奇妙探索

导言 嗨&#xff0c;大家好&#xff01;今天我们要深入了解一项让通信更强大的技术——5G NTN。它和卫星通信结合在一起&#xff0c;为我们带来了通信的新时代。在这篇文章中&#xff0c;我们将用白话文揭示5G NTN和卫星通信的关系&#xff0c;探索这个通信世界的奇妙之旅。 5…...

RabbitMQ的基础使用

/*** 使用rabbitMQ* 1.引用amqp场景 RabbitAutoConfiguration就会自动生效* 2.给容器中自动配置了各种api RabbitTemplate AmqpAdmin CachingConnectionFactory RabbitMessagingTemplate* 所有属性都是 spring.rabbitmq开头* 3.通过注解EnableRabbit使用* 4.监听消息 使用Rabbi…...

使用Uniapp随手记录知识点

使用uniapp随手记录知识点 1 组件内置组件扩展组件 2 vuex状态管理使用流程mapState 辅助函数gettersMutation 1 组件 内置组件 内置组件内主要包含一些基础的view button video scroll-view等内置基础组件&#xff0c;满足基础场景 扩展组件 扩展组件是uniapp封装了一些成…...

Fiber Node的数据结构,以及如何在Reconciliation阶段被使用。

首先&#xff0c;Fiber Node是React用来描述组件树的数据结构&#xff0c;每一个React组件都对应一个Fiber Node。下面是一个Fiber Node的基本结构&#xff1a; const fiber {// 标识这个Fiber Node的类型&#xff08;函数组件&#xff0c;类组件&#xff0c;DOM节点类型等&a…...

Spring Cloud Alibaba 之 Sentinel

大家好&#xff0c;我是升仔 引言 在微服务架构中&#xff0c;服务之间的依赖错综复杂。一旦某个服务出现问题&#xff0c;很容易引发连锁反应&#xff0c;导致整个系统瘫痪。Sentinel 就是为了解决这类问题而生的。它通过流量控制、熔断降级等机制&#xff0c;保护服务不被过多…...

Jenkins Tutorial

什么是Jenkins Jenkins是一个自动化平台&#xff0c;它允许你使用pipelines去部署应用。它也可以自动化其他任务。 BUILDTESTDEPLOYMENT Jenkins 架构 首先&#xff0c;你拥有一个Master Server&#xff0c;它控制pipelines和安排Build到你的Agent上&#xff1b; 其次&…...

css mask 案例

文章目录 一、基本用法二、图案遮罩二、文字阴影效果三、日历探照灯效果 CSS的mask属性用于定义一个可重复使用的遮罩&#xff0c;可以将其应用到任何可视元素上。这个功能类似于Photoshop中的图层蒙版。通过mask属性&#xff0c;可以创建独特的效果&#xff0c;比如圆形、渐变…...

案例系列:Movielens_预测用户对电影的评分_基于行为序列Transformer的推荐系统

文章目录 简介数据集设置准备数据下载并准备数据框将电影评分数据转换为序列 定义元数据为训练和评估创建 tf.data.Dataset创建模型输入编码输入特征创建一个二叉搜索树模型运行训练和评估实验结论 描述&#xff1a; 使用行为序列Transformer&#xff08;BST&#xff09;模型在…...

单词接龙[中等]

一、题目 字典wordList中从单词beginWord和endWord的 转换序列 是一个按下述规格形成的序列beginWord -> s1 -> s2 -> ... -> sk&#xff1a; 1、每一对相邻的单词只差一个字母。 2、对于1 < i < k时&#xff0c;每个si都在wordList中。注意&#xff0c;beg…...

机器人制作开源方案 | 森林管理员

​作者&#xff1a;李佳骏、常睿康、张智斌、李世斌、高华耸 单位&#xff1a;山西能源学院 指导老师&#xff1a;赵浩成、郜敏 1. 研究背景 森林作为地球上可再生自然资源及陆地生态的主体&#xff0c;在人类生存和发展的历史中起着不可代替的作用&#xff0c;它不仅能提供…...

Laravel框架使用phpstudy本地安装的composer用Laravel 安装器进行安装搭建

一、首先需要安装Laravel 安装器 composer global require laravel/installer 二、安装器安装好后&#xff0c;可以使用如下命令创建项目 laravel new sys 三、本地运行 php artisan serve 四、 使用Composer快速安装Laravel5.8框架 安装指定版本的最新版本&#xff08;推荐&a…...

炫酷登录注册界面【超级简单 jQuery+JS+HTML+CSS实现】

一&#xff1a;源码获取 这两天根据需求写了一个比较好看的有动态效果的登录注册切换页面&#xff0c;这里我将源码资源分享给大家&#xff0c;大家可以直接免费下载使用哦&#xff0c;没有 vip 的小伙伴找我私聊发送"登录注册"即可我给你发文件&#xff0c;此登录注…...

2023年国赛高教杯数学建模E题黄河水沙监测数据分析解题全过程文档及程序

2023年国赛高教杯数学建模 E题 黄河水沙监测数据分析 原题再现 黄河是中华民族的母亲河。研究黄河水沙通量的变化规律对沿黄流域的环境治理、气候变化和人民生活的影响&#xff0c;以及对优化黄河流域水资源分配、协调人地关系、调水调沙、防洪减灾等方面都具有重要的理论指导…...

跨国企业传输大文件注意事项和解决方案

随着全球化的推进&#xff0c;越来越多的企业需要在跨国业务合作、项目交付、数据分析等方面展开合作&#xff0c;这就带来了大量大文件的传输需求。大文件传输是指文件大小超过1GB的传输&#xff0c;通常涉及视频、音频、图片、文档、压缩包等多种格式。跨国传输大文件不仅需要…...

【Redis】Redis 的数据类型

有五种常用数据类型&#xff1a;String、Hash、Set、List、SortedSet。以及三种特殊的数据类型&#xff1a;Bitmap、HyperLogLog、Geospatial &#xff0c;其中HyperLogLog、Bitmap的底层都是 String 数据类型&#xff0c;Geospatial 的底层是 Sorted Set 数据类型。 五种常用…...

QT小技巧 - 使用QMovie进行gif切帧

简介 使用QMovie 将 gif 进行切帧&#xff0c; magick 进行合并代码 QString gifPath "E:\\workspace\\qt\\gif2imgs\\203526qre64haq3ccoobqi.gif"; // 你的图片QMovie movie(gifPath); movie.setCacheMode(QMovie::CacheNone);qDebug() << movie.frameCou…...

Pixel Fashion Atelier企业应用:支持Webhook回调的自动化素材生成流水线搭建

Pixel Fashion Atelier企业应用&#xff1a;支持Webhook回调的自动化素材生成流水线搭建 1. 项目背景与价值 Pixel Fashion Atelier是一款基于Stable Diffusion与Anything-v5的图像生成工作站&#xff0c;专为企业级素材生产需求设计。传统AI工具往往面临两大挑战&#xff1a…...

OpenClaw极简部署:Qwen3-VL:30B镜像+飞书5分钟接入

OpenClaw极简部署&#xff1a;Qwen3-VL:30B镜像飞书5分钟接入 1. 为什么选择这个组合&#xff1f; 上周我在测试各种开源模型与自动化工具的搭配方案时&#xff0c;发现了一个效率极高的组合&#xff1a;星图平台的Qwen3-VL:30B镜像OpenClaw框架。这个方案最吸引我的地方在于…...

保姆级避坑指南:Ubuntu系统下Hadoop HA集群搭建,我踩过的那些SSH和配置文件的“坑”

Ubuntu下Hadoop HA集群搭建&#xff1a;那些教科书不会告诉你的实战陷阱 第一次在Ubuntu上搭建Hadoop HA集群时&#xff0c;我天真地以为照着官方文档就能顺利跑起来。直到SSH连接莫名其妙失败、JournalNode权限报错刷屏、ZKFC死活不启动时&#xff0c;才明白为什么有人说大数据…...

WebPlotDigitizer图表数据提取工具:科研工作者的终极数字化解决方案

WebPlotDigitizer图表数据提取工具&#xff1a;科研工作者的终极数字化解决方案 【免费下载链接】WebPlotDigitizer WebPlotDigitizer: 一个基于 Web 的工具&#xff0c;用于从图形图像中提取数值数据&#xff0c;支持 XY、极地、三角图和地图。 项目地址: https://gitcode.c…...

将嵌套循环中的Java对象数组转换为HashMap以优化性能

本文旨在指导开发人员如何通过将嵌套循环转换为Hashmap来优化Java代码的性能&#xff0c;特别是当涉及到对象属性的相等性检查时。通过使用Hashmap的快速搜索特性&#xff0c;可以显著降低时间复杂性&#xff0c;提高代码执行效率。本文将提供详细的步骤和示例代码&#xff0c;…...

别再死记硬背了!用Kahn算法搞定LeetCode 207课程表,保姆级C++代码逐行解析

从课程表到任务调度&#xff1a;Kahn算法在LeetCode 207中的实战应用 每次打开LeetCode看到那道课程表问题&#xff0c;你是不是也感到一阵头疼&#xff1f;先修课程、依赖关系、环状检测……这些概念堆在一起&#xff0c;简直比大学选课系统还让人崩溃。但别担心&#xff0c;今…...

如何实现Flomo到Obsidian的高效迁移与无缝衔接?一站式数据迁移工具全解析

如何实现Flomo到Obsidian的高效迁移与无缝衔接&#xff1f;一站式数据迁移工具全解析 【免费下载链接】flomo-to-obsidian Make Flomo Memos to Obsidian Notes 项目地址: https://gitcode.com/gh_mirrors/fl/flomo-to-obsidian 当你需要将积累已久的Flomo笔记迁移到Obs…...

CentOS7下SSD性能调优实战:iostat与dd命令的黄金组合

CentOS7下SSD性能调优实战&#xff1a;iostat与dd命令的黄金组合 在当今数据驱动的时代&#xff0c;存储性能往往成为系统瓶颈的关键所在。对于使用CentOS7系统的运维工程师来说&#xff0c;如何充分释放SSD硬件的性能潜力&#xff0c;是一个既具挑战性又充满成就感的技术课题。…...

R语言新手必看:如何用pkgbuild和Sys.which检查并安装Rtools(附绑定教程)

R语言开发环境配置全指南&#xff1a;从Rtools安装到编译环境搭建 刚接触R语言的开发者&#xff0c;在尝试从源代码编译安装某些扩展包时&#xff0c;常常会遇到"make not found"之类的错误提示。这通常意味着系统缺少必要的编译工具链。本文将详细介绍如何在Windows…...

零基础入门esp32开发:用快马平台生成第一个led控制程序详解

最近在学ESP32开发&#xff0c;发现对于新手来说&#xff0c;从零开始写代码还是挺有挑战的。不过我发现了一个超好用的工具——InsCode(快马)平台&#xff0c;它可以根据你的需求直接生成可运行的代码&#xff0c;特别适合像我这样的初学者。 项目需求分析 我想实现一个简单的…...