brpc 并发模型选型指南:同步接口、异步接口与 bthread 的取舍之道
【免费下载链接】brpcbrpc is an Industrial-grade RPC framework using C Language, which is often used in high performance system such as Search, Storage, Machine learning, Advertisement, Recommendation etc. brpc means better RPC.项目地址https://gitcode.com/gh_mirrors/brpc3/brpc点击查看免费下载brpc 同时提供异步访问接口和基于 M:N 线程模型的 bthread这让很多开发者面临一个经典困惑同一个场景到底该用同步接口、异步接口还是 bthread本文以官方决策指南为核心完整讲解延时不高用同步、不行用异步、只有多核并行计算才用 bthread的选型原则给出可直接套用的qps × latency判断公式与逐步示例并结合仓库源码bthread.h、bthread.cpp剖析 bthread 的调度代价与适用边界帮助你写出既简单易懂又不失性能的并发代码。一、问题背景brpc 提供的三种并发手段brpc 是工业级的 C RPC 框架一个服务在处理请求时往往面临三类选择手段本质适用场景同步接口阻塞等待 RPC 返回代码线性、简单延时低、QPS 不高时异步接口以回调代替阻塞可获得多核扩展性高并发、大量阻塞等待时bthreadM:N 线程库M 个 bthread 映射到 N 个 pthread单次请求内的多核并行计算bthread 是 brpc 使用的 M:N 线程库其目标是在提高程序并发度的同时降低编码难度并在核数日益增多的 CPU 上提供更好的 scalability 和 cache locality。与常见的 N:1 协程coroutine不同bthread 中一个 bthread 被卡住不会影响其他 bthread其关键技术是 work stealing 调度和 butex让 bthread 与 pthread 可以相互等待和唤醒。二、同步 or 异步用一句话给出结论文档给出的短回答非常明确延时不高时你应该先用简单易懂的同步接口不行的话用异步接口只有在需要多核并行计算时才用 bthread。2.1 为什么异步并不总是更好异步的本质是用回调代替阻塞——有阻塞的地方就有回调。虽然 JavaScript 等单线程语言中回调接受度很高、工作得很好但它和我们在多线程 RPC 服务中需要的回调完全是两码事。区别不在于 lambda 或 future而在于 JavaScript 是单线程的它的回调放到多线程下可能没有一个能跑过竞争太多。单线程的同步方法和多线程的同步方法是完全不同的。有人会设想能不能让服务像多个独立 eventloop 那样跑brpc 生态中确实有过类似尝试ubaserver注意带 a但实际效果糟糕因为阻塞改回调并不简单当阻塞发生在循环、条件分支、深层子函数中时改造特别困难大量老代码、第三方代码根本不可能改造结果代码中会出现不可避免的阻塞导致该线程中其他回调被延迟流量超时server 性能不符合预期。如果你打算把现在的同步代码改造为大量回调结果往往是除了我其他人都看不太懂并且性能可能更差了。文档明确提醒别被鼓吹异步的人迷惑他们写的是从头到尾从下到上全异步且不考虑多线程的代码和你要写的完全是两码事。2.2 brpc 中的异步与单线程异步的本质区别brpc 中的异步和单线程的异步完全不同异步回调会运行在与调用处不同的线程中你会获得多核扩展性但代价是你必须意识到多线程问题。好消息是你可以在回调中阻塞只要线程够用对 server 整体的性能并不会有什么影响。异步代码依然很难写为此 brpc 提供了组合访问combo_channel来简化问题。通过组合不同的 channel如 ParallelChannel你可以声明式地执行复杂的多路访问而不用关心其中的回调细节。从 combo_channel.md 的源码文档看ParallelChannel 支持同步和异步访问、可取消、可超时还能通过CallMapper修改请求、ResponseMerger合并结果这就是组合优于自行维护回调计数器的官方推荐做法。2.3 判断使用同步或异步qps × latency 公式延时不长、qps 不高时官方更建议使用同步接口——这其实也正是创建 bthread 的动机维持同步代码的同时也能提升交互性能。判断公式如下计算 qps × latencylatency 以秒为单位如果结果和 cpu 核数是同一数量级就用同步否则用异步。三个典型示例场景计算过程结论qps 2000latency 10ms2000 × 0.01s 20与常见的 32 核同一数量级用同步qps 100latency 5s100 × 5s 500与核数不在同一数量级用异步qps 500latency 100ms500 × 0.1s 50基本同一数量级可用同步若未来延时继续增长考虑异步公式的物理含义这个公式计算的正是同时进行的平均请求数你可以尝试用 Littles Law 的思路证明它它和线程数、cpu 核数是可比的。解读如下当这个值远大于 cpu 核数时说明大部分操作并不耗费 CPU而是让大量线程阻塞等待中——此时使用异步可以明显节省线程资源主要是线程栈占用的内存当这个值小于或与 cpu 核数差不多时异步能节省的线程资源就很有限了此时简单易懂的同步代码更重要。三、异步 or bthread并发 RPC 与并行计算是两回事有了 bthread 这个工具用户甚至可以自己实现异步。以半同步发起多个操作后统一等待为例brpc 中用户有多种选择发起多个异步 RPC 后挨个 Join阻塞直到 RPC 结束——注意这仅用于和 bthread 对比实现中官方建议使用 ParallelChannel而不是自己 Join启动多个 bthread 各自执行同步 RPC然后挨个 join bthreads。3.1 并发 RPC 场景前者效率更高哪种效率更高显然是前者异步 Join。后者不仅要付出创建 bthread 的代价而且在 RPC 阻塞等待期间bthread 还被白白占用着不能用于其他用途。如果仅仅是为了并发 RPC别用 bthread。3.2 并行计算场景bthread 的用武之地不过当你需要并行计算时问题就不同了。使用 bthread 可以简单地构建树形的并行计算充分利用多核资源。比如检索过程中有三个环节可以并行处理你可以建立两个 bthread 运行两个环节在原地运行剩下的环节最后 join 那两个 bthread。过程大致如下bool search() { ... bthread th1, th2; if (bthread_start_background(th1, NULL, part1, part1_args) ! 0) { LOG(ERROR) Fail to create bthread for part1; return false; } if (bthread_start_background(th2, NULL, part2, part2_args) ! 0) { LOG(ERROR) Fail to create bthread for part2; return false; } part3(part3_args); bthread_join(th1); bthread_join(th2); return true; }对照 bthread.h 中的接口声明可以印证这段代码的两个关键 APIbthread_start_background(tid, attr, fn, args)创建 bthreadfn(args)并把标识符写入tid行为更接近pthread_create——调度新线程运行后立即返回注释明确指出新线程可能比bthread_start_urgent()更晚运行bthread_join(bt, bthread_return)使调用线程等待 bthreadbt终止若bt已终止则立即返回注释Return immediately ifbtis already terminated且bthread_join()不受bthread_interrupt()影响。在 bthread.cpp 的实现中bthread_start_background会优先尝试把新任务放入当前 pthread worker 的本地 TaskGroupg-start_backgroundfalse若调用者不在 worker 线程上则走start_from_non_worker——这就是它创建开销小、调度快的底层来源。这个两线程并行 原地运行实现的两个要点原文 point线程资源更省你当然可以建立三个 bthread 分别执行三个部分再统一 join但相比上面这个方法要多耗费一个 bthread 资源调度延时需要心里有数bthread 从建立到执行是有延时的调度延时。在不是很忙的机器上这个延时的中位数在 3 微秒左右90% 在 10 微秒内99.99% 在 30 微秒内。这带来两个推论计算时间超过 1ms 时收益才比较明显。如果计算非常简单、几微秒就结束了用 bthread 是没有意义的尽量让原地运行的部分最慢。这样 bthread 中的部分即使被延迟了几微秒最后可能还是会先结束从而消除掉调度延迟的影响并且join 一个已结束的 bthread 会立刻返回不会有上下文切换开销。3.3 线程池需求用 bthread 或 ExecutionQueue当你有类似线程池的需求——比如要执行某一类 job 的线程池——也可以用 bthread 代替。如果对 job 的执行顺序有要求可以使用基于 bthread 的 ExecutionQueue。从 execution_queue.md 可以看到ExecutionQueue 提供异步有序执行任务在单独线程中执行执行顺序严格与提交顺序一致、多生产者并发提交、取消已提交任务、stop 以及高优任务插队等能力其任务提交接口是 wait-free 的并且运行线程本身就是 bthread可以在执行函数中随意使用 bthread 同步原语而不必担心阻塞 pthread 的执行——这正是它替代自定义 job 线程池 队列的底气。四、选型决策树与最佳实践总结综合全篇brpc 并发代码的选型可以浓缩为下面的决策路径需要并发处理吗 ├─ 否 → 直接用同步接口最简单、最易维护 └─ 是 ├─ 仅是为了并发 RPC多个下游访问→ 用 ParallelChannel / 异步接口 │ 不要用 bthreadqps × latency 远大于核数时异步收益明显 └─ 需要多核并行计算CPU 密集、可拆分环节 ├─ 子任务耗时 1ms → bthread 树形并行原地跑最慢的一路 ├─ 子任务耗时仅几微秒 → 不值得用 bthread └─ 需要有序执行的一类 job → ExecutionQueue几个被反复强调的关键结论值得作为团队编码规范默认同步按需异步延时不高、QPS 不高时同步接口永远是第一选择它简单、可读、可维护用公式而不是感觉做决策qps × latency(秒)与 cpu 核数对比同一数量级用同步否则用异步并发 RPC 别用 bthread并行 RPC 场景下 bthread 只会徒增创建开销且 RPC 阻塞期间 bthread 被闲置bthread 只服务于并行计算且子任务要足够重 1ms才划算调度延时的中位数在 3 微秒左右复杂组合访问优先用 ParallelChannel有顺序执行需求的 job 队列用 ExecutionQueue。关于 bthread 的更多底层机制work stealing、butex、与 pthread worker 的对应关系、阻塞时的行为可进一步阅读 bthread.md 和 threading_overview.md关于同步/异步接口的完整用法见 client.md 与 combo_channel.md。需要说明的是上述决策框架面向的是以阻塞式业务逻辑为主的通用在线服务如果你的场景运行时间确定、代码严格非阻塞那么 N:1 协程或 eventloop 风格也有其用武之地但那是另一套选型逻辑了。赞分享【免费下载链接】brpcbrpc is an Industrial-grade RPC framework using C Language, which is often used in high performance system such as Search, Storage, Machine learning, Advertisement, Recommendation etc. brpc means better RPC.项目地址https://gitcode.com/gh_mirrors/brpc3/brpc点击查看免费下载相关推荐brpc 并发模型选型指南同步、异步还是 bthreadbrpc 并发模型选型指南同步、异步还是 bthread 这篇技术指南围绕 brpc 中最常见的架构选择题展开当服务需要并发时到底该用同步接口、异步接口后端RPC框架通信网络LanceDB Python API 完整指南同步与异步双接口实战LanceDB Python API 完整指南同步与异步双接口实战 LanceDB 是一个面向多模态 AI 的开发者友好型开源嵌入式向量检索库。本文基于仓库中数据库向量数据库全文检索人工智能PyPTO 核间同步之 wait_cross_core接口语义、同步模式与实战示例PyPTO 核间同步之 wait_cross_core接口语义、同步模式与实战示例 pypto_pro.language.system.wait_cross_人工智能编译器模型编译深度学习高性能计算CANNAscend创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

相关新闻

Signal-3.8-27B本地部署实测:AP-Q4_K_M量化与思考链控制效果

Signal-3.8-27B本地部署实测:AP-Q4_K_M量化与思考链控制效果

1. 这个27B模型到底是个什么来头 Signal-3.8-27B这个名字最近在本地部署圈子里被反复提起,我一开始也是被群里几个老哥安利的。简单说,这是一个270亿参数规模的大语言模型,主打的是"思考能省则省"这个方向——也就是在推理过程中动…

2026/10/9 16:21:31 阅读更多 →
基于Java的实验教学管理系统:排课、成绩与报告一体化实现

基于Java的实验教学管理系统:排课、成绩与报告一体化实现

简介:这是一套基于Java的实验教学管理系统完整源码,专注于高校及培训机构实验教学管理,适合Java后端开发者、Vue前端学习者及需搭建管理后台的工程人员。压缩包共131个文件、约1.95MB,含73个Java源文件、12个Vue组件、12个JavaScr…

2026/10/9 16:21:30 阅读更多 →
Win8/10下安装SQL Server 2005:兼容性设置与故障排查实战

Win8/10下安装SQL Server 2005:兼容性设置与故障排查实战

简介:针对Windows 8、8.1与10系统安装Microsoft SQL Server 2005的兼容性难题,这份PDF教程提供了从启用管理员账户、开启系统功能、安装必备组件到处理程序兼容性提示的完整操作指引,适用于因历史项目或课程要求仍需部署该旧版数据库的运维人…

2026/10/9 16:20:29 阅读更多 →

最新新闻

聚宽SQL数据同步:基于MySQL中转库的增量管道实践

聚宽SQL数据同步:基于MySQL中转库的增量管道实践

简介:面向量化交易与金融数据分析人员,这份压缩包围绕聚宽平台SQL接口的数据传递与中转操作,整理了一套可直接参考的轻量资料,用于解决从聚宽取数到中转数据库落地的需求。包内共3个文件,包含Python脚本、XML配置及rzr…

2026/10/9 17:30:43 阅读更多 →
OCP 19c 083备考:多租户、RMAN与Data Pump实战要点解析

OCP 19c 083备考:多租户、RMAN与Data Pump实战要点解析

简介:面向Oracle OCP 19c-083考试的复习资料,围绕数据库日志恢复、警报监控、网格基础设施升级、PGA内存管理等核心考点展开。内容基于考试真题整理,对Flashback日志空间回收条件、服务器生成警报的手动清除与历史清理、升级网格基础架构的注…

2026/10/9 17:30:43 阅读更多 →
GPT-4.1 Nano 核心能力与实战效果全景展示:把 Codex auth.json 改到 TaoToken

GPT-4.1 Nano 核心能力与实战效果全景展示:把 Codex auth.json 改到 TaoToken

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/9 17:30:41 阅读更多 →
微电网二次控制中的延迟问题:诊断、稳定性影响与工程补偿策略

微电网二次控制中的延迟问题:诊断、稳定性影响与工程补偿策略

微电网的二次控制,说白了就是给整个系统“扶正纠偏”的环节。一次下垂控制把功率分好了,但也留下了频率偏差和电压偏差;二次控制就是那个负责把偏差抹掉的“执行者”。可问题来了,这台执行者一旦患上了“拖延症”——从采样、通信…

2026/10/9 17:30:41 阅读更多 →
ExtJS组件化框架实战:从创建组件到布局通信与封装复用

ExtJS组件化框架实战:从创建组件到布局通信与封装复用

ExtJS 很早就被贴上了"重、老、贵"的标签,很多人一听到它就直接劝退。但如果你真的花时间用过它的组件体系,会有一个完全不同的感受:这根本不是一袋子散装控件,而是一套纪律严明的组件化框架。刚开始被那一堆类名和配置…

2026/10/9 17:30:39 阅读更多 →
数据库物理模型设计实战:字段类型、索引策略与分区方案落地指南

数据库物理模型设计实战:字段类型、索引策略与分区方案落地指南

简介:这份资源聚焦数据库物理模型设计,面向数据库设计人员、后端开发与数据建模学习者,帮助读者理解如何将逻辑模型落地到实际存储系统,兼顾性能优化、存储效率与数据管理。内容以四种核心设计模式为线索,重点讲解主扩…

2026/10/9 17:29:37 阅读更多 →

日新闻

Java时间API实战:LocalDate、Date与ZonedDateTime的转换与避坑指南

Java时间API实战:LocalDate、Date与ZonedDateTime的转换与避坑指南

Java时间API这个话题,隔三差五就会在群里被翻出来讨论一次。上周还有个同事线上处理一个订单超时问题,排查到最后发现是ZonedDateTime序列化后时区丢了,用户在下单当天晚上看到的时间整整差了8个小时。这类问题几乎每个做Java开发的人都遇到过…

2026/10/9 0:00:49 阅读更多 →
EasyTier实践:从NAT穿透到子网代理的异地组网部署与排错

EasyTier实践:从NAT穿透到子网代理的异地组网部署与排错

前几个月我手头有好几台机器需要互相访问:办公室台式机、家里 NAS、还有一台云主机。如果只是偶尔传个文件倒还好,问题是工作场景经常要在几处环境之间来回切换,每次都先登录跳板机再层层代理,实在折腾。我先后试过端口映射、自建…

2026/10/9 0:00:49 阅读更多 →
AI Agent工程实战:从七要素到七个决策点的系统设计指南

AI Agent工程实战:从七要素到七个决策点的系统设计指南

AI Agent 这个词在过去一年里被反复提及,但真正动手搭过一套能跑起来的 Agent 系统的人都知道,从"知道它是什么"到"让它稳定干活"之间隔着一整套工程决策。我前后参与过几个 Agent 项目的落地,从最初用现成框架拼装&…

2026/10/9 0:01:50 阅读更多 →

周新闻

KT148A语音芯片外挂8002D功放的工程实践指南

KT148A语音芯片外挂8002D功放的工程实践指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/8 15:26:32 阅读更多 →
LLC谐振变换器增益公式推导:从FHA等效到完整归一化表达式

LLC谐振变换器增益公式推导:从FHA等效到完整归一化表达式

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/8 15:26:40 阅读更多 →
ARM架构深度解析:从RISC设计理念到交叉编译实战

ARM架构深度解析:从RISC设计理念到交叉编译实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/9 10:11:06 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/8 21:13:17 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/8 15:26:17 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/9 6:17:20 阅读更多 →