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

brpc之io事件分发器

结构

EventDispatcher
+int Start(const bthread_attr_t* consumer_thread_attr)
+int AddConsumer(SocketId socket_id, int fd)
+int RegisterEvent(SocketId socket_id, int fd, bool pollin)
+int UnregisterEvent(SocketId socket_id, int fd, bool pollin)
-static void* RunThis(void* arg)
-void Run()
-int RemoveConsumer(int fd)

初始化

brpc的io事件分发器,使用多线程Reactor模式
通过InitializeGlobalDispatchers来初始化全局io事件分发器
分为task_group_ntags组,每组有event_dispatcher_num

void InitializeGlobalDispatchers() {g_edisp = new EventDispatcher[FLAGS_task_group_ntags * FLAGS_event_dispatcher_num];for (int i = 0; i < FLAGS_task_group_ntags; ++i) {for (int j = 0; j < FLAGS_event_dispatcher_num; ++j) {bthread_attr_t attr =FLAGS_usercode_in_pthread ? BTHREAD_ATTR_PTHREAD : BTHREAD_ATTR_NORMAL;attr.tag = (BTHREAD_TAG_DEFAULT + i) % FLAGS_task_group_ntags;CHECK_EQ(0, g_edisp[i * FLAGS_event_dispatcher_num + j].Start(&attr));}}// This atexit is will be run before g_task_control.stop() because above// Start() initializes g_task_control by creating bthread (to run epoll/kqueue).CHECK_EQ(0, atexit(StopAndJoinGlobalDispatchers));
}

分发策略

EventDispatcher& GetGlobalEventDispatcher(int fd, bthread_tag_t tag) {pthread_once(&g_edisp_once, InitializeGlobalDispatchers);if (FLAGS_task_group_ntags == 1 && FLAGS_event_dispatcher_num == 1) {return g_edisp[0];}int index = butil::fmix32(fd) % FLAGS_event_dispatcher_num;return g_edisp[tag * FLAGS_event_dispatcher_num + index];
}

读事件

对于acceptor,读事件处理函数为OnNewConnections

options.on_edge_triggered_events = OnNewConnections;

连接后新socket的读事件处理函数为OnNewDataFromTcp或者OnNewMessages

#if BRPC_WITH_RDMAif (am->_use_rdma) {options.on_edge_triggered_events = rdma::RdmaEndpoint::OnNewDataFromTcp;} else {
#else{
#endifoptions.on_edge_triggered_events = InputMessenger::OnNewMessages;}

写事件

对于非阻塞connect时,会调用事件分发器的RegisterEvent注册EPOLLOUT

int Socket::Connect(const timespec* abstime,int (*on_connect)(int, int, void*), void* data) {if (_ssl_ctx) {_ssl_state = SSL_CONNECTING;} else {_ssl_state = SSL_OFF;}struct sockaddr_storage serv_addr;socklen_t addr_size = 0;if (butil::endpoint2sockaddr(remote_side(), &serv_addr, &addr_size) != 0) {PLOG(ERROR) << "Fail to get sockaddr";return -1;}butil::fd_guard sockfd(socket(serv_addr.ss_family, SOCK_STREAM, 0));if (sockfd < 0) {PLOG(ERROR) << "Fail to create socket";return -1;}CHECK_EQ(0, butil::make_close_on_exec(sockfd));// We need to do async connect (to manage the timeout by ourselves).CHECK_EQ(0, butil::make_non_blocking(sockfd));const int rc = ::connect(sockfd, (struct sockaddr*)&serv_addr, addr_size);if (rc != 0 && errno != EINPROGRESS) {PLOG(WARNING) << "Fail to connect to " << remote_side();return -1;}if (on_connect) {EpollOutRequest* req = new(std::nothrow) EpollOutRequest;if (req == NULL) {LOG(FATAL) << "Fail to new EpollOutRequest";return -1;}req->fd = sockfd;req->timer_id = 0;req->on_epollout_event = on_connect;req->data = data;// A temporary Socket to hold `EpollOutRequest', which will// be added into epoll device soonSocketId connect_id;SocketOptions options;options.bthread_tag = _bthread_tag;options.user = req;if (Socket::Create(options, &connect_id) != 0) {LOG(FATAL) << "Fail to create Socket";delete req;return -1;}// From now on, ownership of `req' has been transferred to// `connect_id'. We hold an additional reference here to// ensure `req' to be valid in this scopeSocketUniquePtr s;CHECK_EQ(0, Socket::Address(connect_id, &s));// Add `sockfd' into epoll so that `HandleEpollOutRequest' will// be called with `req' when epoll event reachesif (GetGlobalEventDispatcher(sockfd, _bthread_tag).RegisterEvent(connect_id, sockfd, false) !=0) {const int saved_errno = errno;PLOG(WARNING) << "Fail to add fd=" << sockfd << " into epoll";s->SetFailed(saved_errno, "Fail to add fd=%d into epoll: %s",(int)sockfd, berror(saved_errno));return -1;}// Register a timer for EpollOutRequest. Note that the timeout// callback has no race with the one above as both of them try// to `SetFailed' `connect_id' while only one of them can succeed// It also work when `HandleEpollOutRequest' has already been// called before adding the timer since it will be removed// inside destructor of `EpollOutRequest' after leaving this scopeif (abstime) {int rc = bthread_timer_add(&req->timer_id, *abstime,HandleEpollOutTimeout,(void*)connect_id);if (rc) {LOG(ERROR) << "Fail to add timer: " << berror(rc);s->SetFailed(rc, "Fail to add timer: %s", berror(rc));return -1;}}} else {if (WaitEpollOut(sockfd, false, abstime) != 0) {PLOG(WARNING) << "Fail to wait EPOLLOUT of fd=" << sockfd;return -1;}if (CheckConnected(sockfd) != 0) {return -1;}}return sockfd.release();
}

相关文章:

brpc之io事件分发器

结构 #mermaid-svg-v4SjrdGXadMO4udP {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-v4SjrdGXadMO4udP .error-icon{fill:#552222;}#mermaid-svg-v4SjrdGXadMO4udP .error-text{fill:#552222;stroke:#552222;}#merm…...

MySQL | 知识 | 从底层看清 InnoDB 数据结构

文章目录 一、InnoDB 简介InnoDB 行格式COMPACT 行格式CHAR(M) 列的存储格式VARCHAR(M) 最多能存储的数据记录中的数据太多产生的溢出行溢出的临界点 二、表空间文件的结构三、InnoDB 数据页结构页页的概览Infimum 和 Supremum使用Page Directory页的真实面貌 四、B 树是如何进…...

es的封装

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、类和接口介绍0.封装思想1.es的操作分类 二、创建索引1.成员变量2.构造函数2.添加字段3.发送请求4.创建索引总体代码 三.插入数据四.删除数据五.查询数据 前…...

写一个自动化记录鼠标/键盘的动作,然后可以重复执行的python程序

import sys import threading import time from PyQt5.QtWidgets import * from auto_fun import * import pyautogui import pynput from PyQt5.QtCore import pyqtSignal from MouseModule import * from pynput import keyboardlocal_list [] # 保存操作坐标、动作、文本 …...

Spring Boot-热部署问题

Spring Boot 热部署问题分析与解决方案 热部署&#xff08;Hot Deployment&#xff09;是指在应用程序运行过程中&#xff0c;无需停止应用就可以动态加载新代码、配置或资源&#xff0c;从而提升开发效率。在 Spring Boot 开发中&#xff0c;热部署是一项非常实用的功能&…...

深度学习——管理模型的参数

改编自李沐老师《动手深度学习》5.2. 参数管理 — 动手学深度学习 2.0.0 documentation (d2l.ai) 在深度学习中&#xff0c;一旦我们选择了模型架构并设置了超参数&#xff0c;我们就会进入训练阶段。训练的目标是找到能够最小化损失函数的模型参数。这些参数在训练后用于预测&…...

芯片验证板卡设计原理图:372-基于XC7VX690T的万兆光纤、双FMC扩展的综合计算平台 RISCV 芯片验证平台

基于XC7VX690T的万兆光纤、双FMC扩展的综合计算平台 RISCV 芯片验证平台 一、板卡概述 基于V7的高性能PCIe信号处理板&#xff0c;北京太速科技板卡选用Xilinx 公司Virtex7系列FPGA XC7VX690T-2FFG1761C为处理芯片&#xff0c;板卡提供两个标准FMC插槽&#xff0c;适用于…...

【软设】 系统开发基础

【软设】 系统开发基础 一.软件工程概述 &#xff08;了解一下大概的流程就行&#xff09; 1. 可行性分析与项目开发计划 目的&#xff1a;评估项目的经济性、技术性和运营性&#xff0c;判断项目是否值得投资和开发。确定开发时间、预算、所需资源等。 可行性分析&#xff…...

Linux移植之系统烧写

直接参考【正点原子】I.MX6U嵌入式Linux驱动开发指南V1.81 本文仅作为个人笔记使用&#xff0c;方便进一步记录自己的实践总结。 前面我们已经移植好了 uboot 和 linux kernle&#xff0c;制作好了根文件系统。但是我们移植都是通过网络来测试的&#xff0c;在实际的产品开发中…...

【数据结构与算法】LeetCode:双指针法

文章目录 LeetCode&#xff1a;双指针法正序同向而行&#xff08;快慢指针&#xff09;移除元素移动零&#xff08;Hot 100&#xff09;删除有序数组中的重复项颜色分类&#xff08;Hot 100&#xff09;压缩字符串移除链表元素删除排序链表中的重复元素删除排序链表中的重复元素…...

Istio下载及安装

Istio 是一个开源的服务网格&#xff0c;用于连接、管理和保护微服务。以下是下载并安装 Istio 的步骤。 官网文档&#xff1a;https://istio.io/latest/zh/docs/setup/getting-started/ 下载 Istio 前往Istio 发布页面下载适用于您的操作系统的安装文件&#xff0c;或者自动…...

Redis基础数据结构之 Sorted Set 有序集合 源码解读

目录标题 Sorted Set 是什么?Sorted Set 数据结构跳表&#xff08;skiplist&#xff09;跳表节点的结构定义跳表的定义跳表节点查询层数设置 Sorted Set 基本操作 Sorted Set 是什么? 有序集合&#xff08;Sorted Set&#xff09;是 Redis 中一种重要的数据类型&#xff0c;…...

蓝队技能-应急响应篇Web内存马查杀JVM分析Class提取诊断反编译日志定性

知识点&#xff1a; 1、应急响应-Web内存马-定性&排查 2、应急响应-Web内存马-分析&日志 注&#xff1a;传统WEB类型的内存马只要网站重启后就清除了。 演示案例-蓝队技能-JAVA Web内存马-JVM分析&日志URL&内存查杀 0、环境搭建 参考地址&#xff1a;http…...

递归快速获取机构树型图

一般组织架构都会有层级关系&#xff0c;根部门的parentId一般设置为null或者0等特殊字符&#xff0c;而次级部门及以下的parentId则指向他们父节点的id。 以此为基础&#xff0c;业务上经常会有查询整个组织架构层级关系的需求&#xff0c;返回对象中的children属性用来存储子…...

[Web安全 网络安全]-XSS跨站脚本攻击

文章目录&#xff1a; 一&#xff1a;前言 1.定义 2.漏洞出现的原因 3.鉴别可能存在XSS漏洞的地方 4.攻击原理 5.危害 6.防御 7.环境 7.1 靶场 7.2 自动扫描工具 7.3 手工测试工具 8.payload是什么 二&#xff1a;常用的标签语法 三&#xff1a;XSS的分类 反射…...

数据库数据恢复—SQL Server附加数据库出现“错误823”怎么恢复数据?

SQL Server数据库故障&#xff1a; SQL Server附加数据库出现错误823&#xff0c;附加数据库失败。数据库没有备份&#xff0c;无法通过备份恢复数据库。 SQL Server数据库出现823错误的可能原因有&#xff1a;数据库物理页面损坏、数据库物理页面校验值损坏导致无法识别该页面…...

Vscode 中新手小白使用 Open With Live Server 的坑

背景 最近在家学习尝试前端项目打包的一些事项&#xff0c;既然是打包&#xff0c;那么肯定就会涉及到对打包后文件的访问&#xff0c;以直观的查看打包后的效果 那么肯定就会使用到 Vscode 中 Open With LIve Server 这个功能了&#xff0c;首先这个是一个叫 Live Server 的…...

【深度学习 transformer】Transformer与ResNet50在自定义数据集图像分类中的效果比较

在深度学习领域&#xff0c;图像分类是一个经典且重要的任务。近年来&#xff0c;Transformer架构在自然语言处理领域取得了显著成功&#xff0c;逐渐被引入计算机视觉任务。与此同时&#xff0c;ResNet50作为一种经典的卷积神经网络&#xff08;CNN&#xff09;&#xff0c;在…...

【系统架构设计师】专业英语90题(附答案详解)

更多内容请见: 备考系统架构设计师-核心总结索引 文章目录 【第1~5题】【第6~10题】【第11~15题】【第16~20题】【第21~25题】【第26~30题】【第31~35题】【第36~40题】【第41~45题】【第46~50题】【第51~55题】【第56~60题】【第61~65题】【第66~70题】【第71~75题】【第76~8…...

ItemXItemEffect | ItemEffect

目录 ItemXItemEffect ItemEffectID ItemID ItemEffect ID TriggerType Charges CoolDownMSec SpellID SpellCategoryID CategoryCoolDownMSec ItemXItemEffect.db2 ItemEffectID 物品效果编号&#xff0c;取值链接 ItemEffect.db2 ItemID 物品 ID ItemEffect.d…...

Qt/C++开发监控GB28181系统/取流协议/同时支持udp/tcp被动/tcp主动

一、前言说明 在2011版本的gb28181协议中&#xff0c;拉取视频流只要求udp方式&#xff0c;从2016开始要求新增支持tcp被动和tcp主动两种方式&#xff0c;udp理论上会丢包的&#xff0c;所以实际使用过程可能会出现画面花屏的情况&#xff0c;而tcp肯定不丢包&#xff0c;起码…...

盘古信息PCB行业解决方案:以全域场景重构,激活智造新未来

一、破局&#xff1a;PCB行业的时代之问 在数字经济蓬勃发展的浪潮中&#xff0c;PCB&#xff08;印制电路板&#xff09;作为 “电子产品之母”&#xff0c;其重要性愈发凸显。随着 5G、人工智能等新兴技术的加速渗透&#xff0c;PCB行业面临着前所未有的挑战与机遇。产品迭代…...

相机Camera日志实例分析之二:相机Camx【专业模式开启直方图拍照】单帧流程日志详解

【关注我&#xff0c;后续持续新增专题博文&#xff0c;谢谢&#xff01;&#xff01;&#xff01;】 上一篇我们讲了&#xff1a; 这一篇我们开始讲&#xff1a; 目录 一、场景操作步骤 二、日志基础关键字分级如下 三、场景日志如下&#xff1a; 一、场景操作步骤 操作步…...

深入浅出:JavaScript 中的 `window.crypto.getRandomValues()` 方法

深入浅出&#xff1a;JavaScript 中的 window.crypto.getRandomValues() 方法 在现代 Web 开发中&#xff0c;随机数的生成看似简单&#xff0c;却隐藏着许多玄机。无论是生成密码、加密密钥&#xff0c;还是创建安全令牌&#xff0c;随机数的质量直接关系到系统的安全性。Jav…...

oracle与MySQL数据库之间数据同步的技术要点

Oracle与MySQL数据库之间的数据同步是一个涉及多个技术要点的复杂任务。由于Oracle和MySQL的架构差异&#xff0c;它们的数据同步要求既要保持数据的准确性和一致性&#xff0c;又要处理好性能问题。以下是一些主要的技术要点&#xff1a; 数据结构差异 数据类型差异&#xff…...

DIY|Mac 搭建 ESP-IDF 开发环境及编译小智 AI

前一阵子在百度 AI 开发者大会上&#xff0c;看到基于小智 AI DIY 玩具的演示&#xff0c;感觉有点意思&#xff0c;想着自己也来试试。 如果只是想烧录现成的固件&#xff0c;乐鑫官方除了提供了 Windows 版本的 Flash 下载工具 之外&#xff0c;还提供了基于网页版的 ESP LA…...

Ascend NPU上适配Step-Audio模型

1 概述 1.1 简述 Step-Audio 是业界首个集语音理解与生成控制一体化的产品级开源实时语音对话系统&#xff0c;支持多语言对话&#xff08;如 中文&#xff0c;英文&#xff0c;日语&#xff09;&#xff0c;语音情感&#xff08;如 开心&#xff0c;悲伤&#xff09;&#x…...

dify打造数据可视化图表

一、概述 在日常工作和学习中&#xff0c;我们经常需要和数据打交道。无论是分析报告、项目展示&#xff0c;还是简单的数据洞察&#xff0c;一个清晰直观的图表&#xff0c;往往能胜过千言万语。 一款能让数据可视化变得超级简单的 MCP Server&#xff0c;由蚂蚁集团 AntV 团队…...

GruntJS-前端自动化任务运行器从入门到实战

Grunt 完全指南&#xff1a;从入门到实战 一、Grunt 是什么&#xff1f; Grunt是一个基于 Node.js 的前端自动化任务运行器&#xff0c;主要用于自动化执行项目开发中重复性高的任务&#xff0c;例如文件压缩、代码编译、语法检查、单元测试、文件合并等。通过配置简洁的任务…...

Netty从入门到进阶(二)

二、Netty入门 1. 概述 1.1 Netty是什么 Netty is an asynchronous event-driven network application framework for rapid development of maintainable high performance protocol servers & clients. Netty是一个异步的、基于事件驱动的网络应用框架&#xff0c;用于…...