<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Concurrency on Yu's Space</title><link>https://code-agree.github.io/tags/concurrency/</link><description>Recent content in Concurrency on Yu's Space</description><generator>Hugo -- gohugo.io</generator><language>en</language><lastBuildDate>Fri, 07 Aug 2026 09:00:00 +0800</lastBuildDate><atom:link href="https://code-agree.github.io/tags/concurrency/index.xml" rel="self" type="application/rss+xml"/><item><title>MengRao/SPSC_Queue 源码精读：把跨核延迟做到 50ns 的四种 SPSC 队列设计</title><link>https://code-agree.github.io/blog/2026-08-07-spsc_queue_mengrao/</link><pubDate>Fri, 07 Aug 2026 09:00:00 +0800</pubDate><guid>https://code-agree.github.io/blog/2026-08-07-spsc_queue_mengrao/</guid><description>MengRao/SPSC_Queue 是国内低延迟圈知名开发者饶萌（tcpshm、fmtlog 的作者）开源的单生产者单消费者无锁队列，README 宣称 10–200B 消息的跨核通信延迟在 50–100ns。整个仓库只有 4 个头文件、每个不到 150 行，却把 SPSC 队列设计空间里几乎所有关键取舍都覆盖了：定长 vs 变长消息、IPC crash-safe vs 极致延迟。本文逐个拆解这四个实现，重点回答一个问题：同样是无锁环形队列，凭什么它能比教科书写法快一倍？拆完源码后，文章会再退一步补齐全景：支撑这一切的寻址/缓存一致性/内存序三层地基，以及走出 SPSC 之后 MPSC/MPMC 的核心机制与选型。
一、仓库总览：一个 2×2 设计矩阵 #四个头文件不是四个孤立实现，而是两个维度的组合：
定长消息（模板参数 T） 变长消息（带 MsgHeader） 原子发布，crash-safe，可用于共享内存 IPC SPSCQueue.h SPSCVarQueue.h（用于作者的 tcpshm 框架） 极致延迟优化，仅限线程间 SPSCQueueOPT.h SPSCVarQueueOPT.h 两行的本质区别只有一条：消费者靠什么发现新消息。
基础版：消费者轮询生产者发布的共享索引 write_idx——发现消息要读 两条缓存行（索引一条、数据一条）； OPT 版：把&amp;quot;有没有消息&amp;quot;这个标志内嵌进数据所在的缓存行——发现消息只要读 一条缓存行。 跨核通信的延迟基本上就是缓存行在两个核之间传输的次数 × 单次传输耗时（几十 ns）。OPT 版把次数从 2 降到 1，延迟近乎减半——这是整个仓库最核心的亮点。代价是发布操作从&amp;quot;单条原子 store&amp;quot;变成多步写入，进程中途崩溃会把队列留在不一致状态，所以 OPT 版不能用于共享内存 IPC。
在深入源码之前，先交代两件事：这类队列在设计空间里的位置（它是&amp;quot;队列&amp;quot;，不是&amp;quot;广播&amp;quot;），以及四个实现共享的三条&amp;quot;设计基因&amp;quot;。
延伸阅读：并发原语的硬件成本（MESI、原子指令、六种内存序）可以先看这篇打底：并发原语深度剖析：从 Mutex 到 Atomic 到 Lock-Free 数据结构
二、队列还是广播：一个先于所有代码的设计决策 #深入源码前值得先停一步。SPSC_Queue 的一切设计都建立在一个前提上：读者的消费进度（read_idx）放在共享结构里，写者看得见。这个决策先于所有实现细节，直接划定了这类队列的能力边界——它的对立面是把读进度私有化的&amp;quot;广播&amp;quot;模型：</description></item><item><title>并发原语与内存序深度剖析：从 Mutex 到 Atomic 到 Lock-Free 数据结构</title><link>https://code-agree.github.io/blog/2026-03-03-mutext/</link><pubDate>Tue, 03 Mar 2026 23:39:27 +0800</pubDate><guid>https://code-agree.github.io/blog/2026-03-03-mutext/</guid><description>本文系统梳理 Linux/x86_64 环境下各种并发同步机制的实现原理、硬件行为和性能开销，并完整讲解 C++ 内存模型与六种内存序的语义、典型误用与调试方法，为 HFT 场景下的并发设计提供决策依据。本文是本站内存序主题的权威出处，其他文章涉及内存序时均链接至此。
一、硬件基础：理解开销的根源 #在讨论任何同步原语之前，必须先理解 CPU 缓存一致性协议，因为所有同步开销的本质都是 cache line 在核间的传输。
1.1 MESI 协议 #现代多核 CPU 通过 MESI 协议（Modified, Exclusive, Shared, Invalid）维护缓存一致性：
Core 0 Core 1 ┌──────────┐ ┌──────────┐ │ L1 Cache │ │ L1 Cache │ │ Line X: │ │ Line X: │ │ Modified │ │ Invalid │ └────┬─────┘ └────┬─────┘ │ │ └──────┬──────────────┘ │ ┌──────┴──────┐ │ L3 Cache │ (或 Directory) │ / Ring Bus│ └─────────────┘ 四种状态：</description></item><item><title>SPSC DTO 构造语义优化复盘</title><link>https://code-agree.github.io/blog/2025-11-08-default/</link><pubDate>Sat, 08 Nov 2025 00:47:42 +0800</pubDate><guid>https://code-agree.github.io/blog/2025-11-08-default/</guid><description>背景 #最近一次 panda-datatype 提交中，LockFreeRingBuffer 的读写索引放宽为 memory_order_relaxed，同时将行情/订单相关 DTO（Depth5、OrderUpdate、TradeUpdate 等）的默认构造方式改为“成员内联默认值 + = default”。这看似语法微调，实则是为单生产者单消费者（SPSC）数据通道消除隐藏成本。
旧实现的隐患 #旧版在 .cpp 里手写构造函数逐字段清零，逻辑直观，却带来三个问题：
失去平凡属性：自定义构造/析构一旦出现，类型就不再是 trivially constructible/copyable，无法放心地按位拷贝。无锁结构如 LockFreeRingBuffer&amp;lt;std::array&amp;lt;T&amp;gt;&amp;gt; 一旦直接覆盖槽位，轻则报错、重则 UB。 破坏无锁假设：SPSC 设计假定“写入即内存搬运”。如果数组槽位里的 T 有非平凡构造，buffer[index] = item; 就不得不调用它，整条“无锁 + 放宽内存序”路径失效。 维护负担重：新增字段必须同步修改 .cpp 构造，否则默认值遗漏；默认值散落在实现文件，代码审查也不直观。 新方案：成员默认值 + 默认化构造 #提交中 OrderUpdate 的具体修改如下（TradeUpdate 类似）：
struct OrderUpdate { Exchange m_exchange = Exchange::UNKNOWN; uint32_t m_accountId = 0; std::array&amp;lt;char, 32&amp;gt; m_clientOrderId = {}; OrderStatus m_status = OrderStatus::UNKNOWN; int32_t m_errorStatusCode = 0; std::array&amp;lt;char, 64&amp;gt; m_errorReason = {}; OrderUpdate() = default; }; Depth5 也简化为：</description></item><item><title>高频交易系统中的背压机制设计讨论</title><link>https://code-agree.github.io/blog/2025-07-15-backpress/</link><pubDate>Tue, 15 Jul 2025 19:36:31 +0800</pubDate><guid>https://code-agree.github.io/blog/2025-07-15-backpress/</guid><description>摘要 #在高频交易（HFT）系统中，当市场数据突发性爆增时，如何在保证超低延迟的前提下防止系统过载是一个关键技术挑战。本文深入分析了背压机制的原理、常见实现方式，并针对HFT系统的特殊需求，设计了一套基于数据优先级分层的混合背压策略。通过理论分析证明，该方案在保证关键数据零丢失的同时，能够有效应对trade数据的burst场景。
1. 背景与问题定义 #1.1 HFT系统的数据特征 #高频交易系统通常需要处理三类核心市场数据：
BBO（Best Bid Offer）数据：实时更新，对策略决策至关重要，频率约1000-10000次/秒 Orderbook数据：通常100ms更新一次，提供市场深度信息，数据量中等 Trade数据：实时更新，频率极高且具有突发性（burst）特征，正常情况下1000-5000次/秒，burst时可达50000+次/秒 1.2 Burst问题的本质 #在某些市场事件（如重大新闻发布、大单成交）触发下，trade数据可能在毫秒级时间窗口内激增至正常流量的10-100倍。这种突发性负载会导致：
内存溢出：缓冲区被大量trade数据填满 延迟恶化：处理延迟从微秒级恶化到毫秒级 数据丢失：关键的BBO和orderbook更新被遗漏 系统崩溃：极端情况下导致OOM或死锁 2. 背压机制理论基础 #2.1 背压的定义与数学模型 #背压（Backpressure）是一种流控制机制，当系统下游处理能力不足时，向上游传递&amp;quot;减缓输入&amp;quot;的信号，从而维持系统稳定性。
设系统输入速率为λ（events/second），处理速率为μ，缓冲区大小为B：
稳定条件：λ ≤ μ 缓冲区利用率：ρ = λ/μ 背压触发阈值：当缓冲区占用率 &amp;gt; θ（通常θ = 0.8）时启动 当λ &amp;gt; μ时，缓冲区积压量呈线性增长：
积压量(t) = (λ - μ) × t + 初始积压 背压机制的目标是通过动态调整有效输入速率λ&amp;rsquo;，使得λ&amp;rsquo; ≤ μ，从而保证系统稳定性。
2.2 背压的质量评估指标 # 延迟保障：P99延迟 &amp;lt; 目标阈值 吞吐保持：关键数据处理率 ≥ 99% 系统稳定性：内存使用率 &amp;lt; 安全阈值 数据完整性：重要数据丢失率 &amp;lt; 0.01% 3. 常见背压机制分析 #3.1 阻塞式背压（Blocking Backpressure） #原理：当缓冲区满时，阻塞生产者直到有空间可用。</description></item><item><title>深入理解 False Sharing：实测原子操作与缓存行对齐对性能的影响</title><link>https://code-agree.github.io/blog/2025-06-23-cache_false_sharing_analysis/</link><pubDate>Mon, 23 Jun 2025 15:39:27 +0800</pubDate><guid>https://code-agree.github.io/blog/2025-06-23-cache_false_sharing_analysis/</guid><description>目录 #1. 引言 # False Sharing概念介绍 文章研究目标 2. 测试设计概览 # 测试用例矩阵 测试方法说明 3. 样例运行结果 # 普通变量 + False Sharing 普通变量 + 无False Sharing 原子变量 + False Sharing 原子变量 + 无False Sharing 4. 现象分析与原理解释 # False Sharing如何降低性能 alignas(64)避免False Sharing的原理 cache miss升高的原因分析 原子变量性能开销分析 5. 深入理解缓存一致性与原子操作 # MESI缓存一致性协议详解 普通变量与原子变量的对比 原子变量 + False sharing的性能影响 CPU指令层面的差异 缓存一致性协议的影响 微架构层面的详细分析 6. 实战优化建议 # 不同场景的优化策略 7. 总结 # False Sharing的关键要点 核心结论 8. 参考资料与相关阅读 #9. 附录：完整测试代码 # 引言 #在现代多核处理器架构中，缓存系统在性能中扮演着至关重要的角色。然而，当多个线程同时操作位于同一缓存行（Cache Line）内的不同变量时，即使它们并未共享变量本身，也可能导致频繁的缓存一致性协议交互，这就是著名的性能杀手——False Sharing。</description></item><item><title>C++原子操作内存序性能分析：seq_cst vs relaxed</title><link>https://code-agree.github.io/blog/2025-06-21-memory_order_performance_analysis/</link><pubDate>Sat, 21 Jun 2025 00:47:52 +0800</pubDate><guid>https://code-agree.github.io/blog/2025-06-21-memory_order_performance_analysis/</guid><description>摘要 #本文分析了C++原子操作中不同内存序(memory ordering)对性能的影响，特别是比较了默认的顺序一致性(seq_cst)与宽松(relaxed)内存序在x86-64架构上的性能差异。通过实验测试、性能分析和汇编代码检查，我们发现即使在内存模型较强的x86架构上，不同内存序的选择仍然会产生可测量的性能差异。
1. 实验设计 #1.1 测试程序 #我们设计了两个版本的测试程序，它们在固定时间内执行原子变量的读取和计数操作，唯一区别是原子变量读取时使用的内存序不同：
seq_cst版本 (默认内存序):
void worker_seq_cst() { while (running_) { // 默认使用 seq_cst counter_.fetch_add(1, std::memory_order_relaxed); busy_loop(); } } relaxed版本 (显式指定宽松内存序):
void worker_relaxed_load() { while (running_.load(std::memory_order_relaxed)) { counter_.fetch_add(1, std::memory_order_relaxed); busy_loop(); } } 1.2 编译与执行环境 #测试程序使用以下命令编译：
g++ -std=c++11 -O0 -pthread atomic_test_seq_cst.cpp -o test_gcc_seq_cst g++ -std=c++11 -O0 -pthread atomic_test_relaxed.cpp -o test_gcc_relaxed 每个程序运行5秒钟，记录在此期间完成的操作次数。同时使用perf工具收集性能数据：
perf record -e cpu-clock:pppH ./test_gcc_seq_cst perf record -e cpu-clock:pppH ./test_gcc_relaxed 2. 实验结果 #2.1 执行计数结果 # 版本 操作计数 seq_cst 26,494,108 relaxed 26,660,082 性能差异：</description></item><item><title>LockFreeEventBus：从死锁案例到性能剖析</title><link>https://code-agree.github.io/blog/2025-06-20-lockfree_eventbus_performance_analysis/</link><pubDate>Fri, 20 Jun 2025 14:38:58 +0800</pubDate><guid>https://code-agree.github.io/blog/2025-06-20-lockfree_eventbus_performance_analysis/</guid><description>概述 #本文是 LockFreeEventBus 的完整记录，分上下两部分：
上篇（第 1–5 节）：它的来历——一次真实的生产死锁排查，以及如何把基于互斥锁的 EventBus 重构为&amp;quot;无锁队列 + 异步分发&amp;quot;； 下篇（第 6–10 节）：对重构后的 LockFreeEventBus 做机制剖析与性能瓶颈分析——RTTI 分发、智能指针、false sharing 三大开销，以及针对性的优化建议。 背景阅读：文中涉及的无锁队列基础（内存序、环形缓冲、SPSC/MPMC 取舍）见SPSC 队列设计。
1. 问题发现：一次例行监控中的停顿 #在高频交易系统中，每一毫秒都至关重要。一次例行的系统监控中，注意到系统偶尔会出现短暂的停顿。通过日志分析，发现 MarketDataReader 的 readingLoop() 函数只执行了一次就停止了。
2. 定位：日志与 GDB 线程堆栈 #首先查看 MarketDataReader 的日志：
[2024-09-01 13:02:08.472] [main_logger] [MarketDataReader.cpp:38] [info] [thread 4048966] [start] Starting market data reader... [2024-09-01 13:02:08.472] [main_logger] [MarketDataReader.cpp:40] [info] [thread 4048966] [start] Starting start,and running_ = true [2024-09-01 13:02:08.489] [main_logger] [MarketDataReader.cpp:63] [info] [thread 4048967] [readingLoop] Starting reading loop.</description></item><item><title>高频交易中的订单数据结构设计与性能优化实战</title><link>https://code-agree.github.io/blog/2025-06-19-how_to_design_order_inlocalmemory/</link><pubDate>Thu, 19 Jun 2025 19:58:31 +0800</pubDate><guid>https://code-agree.github.io/blog/2025-06-19-how_to_design_order_inlocalmemory/</guid><description>主题：基于并发读写性能优化的订单数据结构重构与底层机制剖析
目录 # 一、业务背景：订单状态的高并发维护 二、常见设计陷阱：char[] 字符串 ID 与哈希表的性能瓶颈 三、优化目标：极致的并发 + O(1) 访问性能 四、核心优化：整数 ID + array 映射结构 五、底层原理解析：为什么 array + int ID 更快? 1. 内存寻址机制(指针偏移) 2. CPU Cache Line 利用与伪共享问题 3. 避免堆分配与内存碎片 4. 内存序(Memory Ordering)选择与原子操作 5. 整数ID分配和回收机制 六、性能测试数据 七、关键组件优化示例 1. OrderBook实现优化 2. RingBuffer优化 八、NUMA架构下的内存访问优化 九、最终方案优势对比总结 十、结语：高频系统的设计哲学 一、业务背景：订单状态的高并发维护 #在高频交易(HFT)系统中，我们需要对数百万级别的订单状态进行并发读写，以支撑如下操作：
✅ 新增订单(add_order(order_id)) ✅ 修改订单状态(如 fill_qty, status 等) ✅ 高频查询订单状态(如成交均价、当前剩余量等) 这些操作高并发、延迟敏感，需要 O(1) 级别的响应，并且不能产生性能抖动或不可控的锁竞争。
二、常见设计陷阱：char[] 字符串 ID 与哈希表的性能瓶颈 #在早期系统中，常见的设计是以字符串 ID 作为订单主键，例如：
struct Order { char id[32]; char instId[16]; .</description></item><item><title>共享内存多进程通信中的页面切换同步问题分析与解决</title><link>https://code-agree.github.io/blog/2025-06-24-fix_shared_page_position/</link><pubDate>Fri, 17 Jan 2025 04:21:23 +0800</pubDate><guid>https://code-agree.github.io/blog/2025-06-24-fix_shared_page_position/</guid><description>问题现象 #在多进程共享内存通信中，发现读取进程出现异常：
写入进程（线程3002707）正常写入数据
读取进程（线程3002791）卡在固定位置：
page: 0 write_pos: 134209160 read_pos: 134199368 问题定位过程 #1. 初步分析 #首先观察到一个关键现象：
Binance的读写正常 Bitget的读取卡在固定位置 两个交易所使用相同的共享内存机制 2. 代码分析 #检查共享内存管理的核心类：
写入机制： template&amp;lt;typename T&amp;gt; bool write(const TypedFrame&amp;lt;T&amp;gt;&amp;amp; frame) { // ... if (write_pos + frame_size &amp;gt; page_size_) { switchToNextPage(); write_pos = current_write_pos_.load(std::memory_order_relaxed); continue; } // ... std::atomic&amp;lt;size_t&amp;gt;* shared_write_pos = reinterpret_cast&amp;lt;std::atomic&amp;lt;size_t&amp;gt;*&amp;gt;(current_page_-&amp;gt;getData()); shared_write_pos-&amp;gt;store(write_pos + frame_size, std::memory_order_release); } 页面切换： void Journal::switchToNextPage() { current_page_ = page_engine_-&amp;gt;getNextPage(); current_write_pos_.store(0, std::memory_order_relaxed); } Page* PageEngine::getNextPage() { current_page_index_++; if (current_page_index_ &amp;gt;= pages_.</description></item><item><title>高频交易系统中的重连机制最佳实践</title><link>https://code-agree.github.io/blog/2025-06-24-atomic_operations_reconnection_mechanism/</link><pubDate>Fri, 27 Sep 2024 01:35:21 +0800</pubDate><guid>https://code-agree.github.io/blog/2025-06-24-atomic_operations_reconnection_mechanism/</guid><description>高频交易系统中的重连机制最佳实践 #背景 #在高频交易系统中，网络连接的稳定性至关重要。然而，由于网络波动或其他原因，连接可能会中断。为了确保系统的连续性和可靠性，需要实现一个高效的重连机制。然而，频繁的重连检查和处理可能导致重复重连，影响系统性能。
问题描述 #在现有实现中，主循环频繁检查 m_client-&amp;gt;needsReconnection()，如果需要重连，则调用 handleReconnect()。然而，由于主循环速度很快，可能在 resetReconnectionFlag() 生效前再次检查 needsReconnection()，导致重复调用 handleReconnect()。
解决方案 #通过使用原子操作和双重检查机制，确保重连过程的原子性和一致性，避免重复重连。
1. 定义连接状态管理 #使用原子变量来管理连接状态，确保线程安全。
class WebSocketClient { private: std::atomic&amp;lt;bool&amp;gt; isReconnecting{false}; std::atomic&amp;lt;bool&amp;gt; needsReconnection{false}; public: bool needsReconnection() const { return needsReconnection.load(std::memory_order_acquire); } bool tryInitiateReconnection() { bool expected = false; return isReconnecting.compare_exchange_strong(expected, true, std::memory_order_acq_rel); } void setNeedsReconnection(bool value) { needsReconnection.store(value, std::memory_order_release); } void resetReconnectionFlag() { needsReconnection.store(false, std::memory_order_release); isReconnecting.store(false, std::memory_order_release); } }; 2. 修改主循环 #在主循环中使用双重检查机制，确保重连过程的原子性。
void StrategyAndTrading::run() { initializeConnection(); marketDataReader-&amp;gt;start(); positionManager-&amp;gt;updatePositionsThread(); m_commonLib-&amp;gt;getConfigManager().configWatcher(); while (running_) { if (m_client-&amp;gt;needsReconnection() &amp;amp;&amp;amp; m_client-&amp;gt;tryInitiateReconnection()) { handleReconnect(); } // 执行其他高频交易逻辑 std::this_thread::sleep_for(std::chrono::microseconds(100)); // 微秒级的睡眠 } } 3.</description></item><item><title>高频交易系统中的高层锁定：必要性与实现</title><link>https://code-agree.github.io/blog/2025-06-24-mutex_performance_analysis/</link><pubDate>Wed, 18 Sep 2024 17:29:59 +0800</pubDate><guid>https://code-agree.github.io/blog/2025-06-24-mutex_performance_analysis/</guid><description>在高频交易系统的开发中，我们经常面临着性能和正确性之间的权衡。最近，我们在优化订单处理流程时，发现了一个有趣的问题：是否需要在高层组件中实现锁定？本文将深入探讨这个问题，分析其必要性，并展示优化前后的实现。
背景 我们的系统主要由以下组件构成：
MmapOrderBook：核心数据存储，使用内存映射文件实现 PositionManager：负责仓位管理 OrderValidator：负责订单验证 OrderManager：负责订单处理流程 最初，我们的实现如下：
// OrderManager.cpp bool OrderManager::processOrder(const MmapOrderBook::Order&amp;amp; order) { if (!orderValidator_-&amp;gt;validateOrder(order)) { return false; } if (orderBook_-&amp;gt;addOrder(order)) { auto position = positionManager_-&amp;gt;getPosition(order.accountId, /* instrumentId */); if (position) { position-&amp;gt;quantity += order.isBuy ? order.quantity : -order.quantity; positionManager_-&amp;gt;updatePosition(*position); } // 发布订单已处理事件 return true; } return false; } 问题分析 虽然 MmapOrderBook 内部使用了分片锁来保证单个操作的线程安全，但我们发现这种方法在处理复合操作时可能存在问题。主要原因如下：
a) 复合操作的原子性： processOrder 方法包含多个相关操作（验证、添加、更新仓位），这些操作需要作为一个原子单元执行。
b) 避免竞态条件： 在验证订单和添加订单之间，系统状态可能发生变化，导致基于过时信息做出决策。
c) 保持不变量： 某些业务逻辑依赖于多个相关数据的一致状态，需要在整个操作过程中维护这些不变量。
d) 简化并发模型： 高层锁定可以简化并发模型，使代码更易于理解和维护。
e) 防止死锁： 复杂操作中可能需要获取多个低层锁，增加死锁风险。高层锁可以降低这种风险。</description></item><item><title>行情链路上的队列取舍与 WebSocket 接收优化</title><link>https://code-agree.github.io/blog/2025-06-24-advanced_queue_usage_patterns/</link><pubDate>Sun, 15 Sep 2024 04:03:51 +0800</pubDate><guid>https://code-agree.github.io/blog/2025-06-24-advanced_queue_usage_patterns/</guid><description>行情链路上的队列取舍与 WebSocket 接收优化 #在高频交易(HFT)系统中,行情从交易所 WebSocket 到策略引擎的链路上,每一微秒的延迟都可能转化为实际的经济损失。本文讨论这条链路上的两个关键决策:WebSocket 消息接收机制怎么设计,以及行情数据要不要经过队列。
1. WebSocket消息接收机制优化 #在高频交易系统中,每一毫秒的延迟都可能导致巨大的经济损失。因此,优化WebSocket消息的接收机制对于系统的整体性能至关重要。
1.1 WebSocketClient类设计与实现 #以下是一个高效的WebSocketClient类的实现示例:
class WebSocketClient { public: using MessageHandler = std::function&amp;lt;void(const char*, size_t)&amp;gt;; WebSocketClient(/* 构造函数参数 */) : ws_(nullptr), running_(false) {} void receiveMessages(MessageHandler handler) { if (!ws_) { throw std::runtime_error(&amp;#34;WebSocket is not connected&amp;#34;); } constexpr size_t BUFFER_SIZE = 1024 * 1024; // 1MB buffer std::array&amp;lt;char, BUFFER_SIZE&amp;gt; buffer; int flags; while (running_) { try { int n = ws_-&amp;gt;receiveFrame(buffer.data(), buffer.size(), flags); if (n &amp;gt; 0) { handler(buffer.</description></item></channel></rss>