-
Notifications
You must be signed in to change notification settings - Fork 0
API Reference
本页面提供 MCCC (Multi-Channel Communication Controller) 库的完整 API 参考文档。
- AsyncBus
- MessagePriority
- MessageHeader
- MessageEnvelope
- BackpressureLevel
- PerformanceMode
- BusStatisticsSnapshot
- FixedString
- FixedVector
- FixedFunction
- make_overloaded
- Component
- StaticComponent
核心消息总线类。基于无锁 MPSC 环形缓冲实现,支持多生产者单消费者模式。
模板参数 PayloadVariant 为 std::variant<T1, T2, ...>,定义总线可承载的所有消息类型。
static AsyncBus& Instance();获取全局单例引用。线程安全 (Meyers' singleton)。
-
返回值:
AsyncBus&-- 总线单例引用 - 线程安全: 是 (C++11 静态局部变量保证)
template <typename T>
bool Publish(T&& message);发布一条消息到总线。使用发送者的默认优先级进行背压准入判断。
-
模板参数:
T-- 消息类型,必须是PayloadVariant的可选类型之一 -
参数:
message-- 待发布的消息,支持移动语义 -
返回值:
true入队成功;false队列已满或背压拒绝 - 线程安全: 是 (lock-free CAS enqueue)
template <typename T>
bool PublishWithPriority(T&& message, MessagePriority priority);以指定优先级发布消息。高优先级消息在背压场景下有更高的准入概率。
-
模板参数:
T-- 消息类型 -
参数:
-
message-- 待发布的消息 -
priority-- 消息优先级 (LOW/MEDIUM/HIGH)
-
-
返回值:
true入队成功;false被背压丢弃 - 线程安全: 是
template <typename T>
bool PublishFast(T&& message);快速发布,跳过背压检查和统计计数。适用于已知队列不会满的场景或对延迟极度敏感的热路径。
-
模板参数:
T-- 消息类型 -
参数:
message-- 待发布的消息 -
返回值:
true入队成功;false队列物理已满 - 线程安全: 是
template <typename T>
uint32_t Subscribe(std::function<void(const T&)> callback);订阅指定类型的消息。当总线分发该类型消息时,回调函数被调用。
-
模板参数:
T-- 要订阅的消息类型 -
参数:
callback-- 消息处理回调函数 -
返回值:
uint32_t-- 订阅 ID,用于后续取消订阅 - 线程安全: 需要获取写锁 (shared_mutex),不应在热路径调用
void Unsubscribe(uint32_t subscription_id);取消订阅。
-
参数:
subscription_id--Subscribe()返回的订阅 ID - 线程安全: 需要获取写锁
uint32_t ProcessBatch(uint32_t max_count = 256);从队列中批量取出消息并通过回调表分发。使用 shared_mutex 读锁查找已注册的回调。
-
参数:
max_count-- 单批次最大处理消息数,默认 256 -
返回值:
uint32_t-- 实际处理的消息数量 - 线程安全: 必须由单一消费者线程调用 (MPSC 约束)
template <typename Visitor>
uint32_t ProcessBatchWith(Visitor&& visitor, uint32_t max_count = 256);使用 std::visit + Visitor 模式批量处理消息。编译期分发,无需查找回调表,无 shared_mutex 开销。
-
模板参数:
Visitor-- 可调用对象,需为每个PayloadVariant中的类型提供operator() -
参数:
-
visitor-- 访问者对象 -
max_count-- 单批次最大处理消息数
-
-
返回值:
uint32_t-- 实际处理的消息数量 - 线程安全: 必须由单一消费者线程调用
-
性能: 比
ProcessBatch()快 19%~42%
enum class MessagePriority : uint8_t {
LOW = 0, // 背压准入阈值 60%
MEDIUM = 1, // 背压准入阈值 80%
HIGH = 2 // 背压准入阈值 99%
};消息优先级枚举。当队列水位超过对应阈值时,该优先级的消息将被丢弃。
| 优先级 | 准入阈值 | 说明 |
|---|---|---|
LOW |
60% | 普通消息,队列超过 60% 容量时开始丢弃 |
MEDIUM |
80% | 重要消息,队列超过 80% 容量时开始丢弃 |
HIGH |
99% | 关键消息,仅在队列几乎满时才丢弃 |
struct MessageHeader {
uint64_t msg_id; // 全局唯一消息 ID (原子递增)
uint64_t timestamp_us; // 微秒级时间戳 (steady_clock)
uint32_t sender_id; // 发送者 ID
MessagePriority priority; // 消息优先级
};消息头部结构,附加在每条消息的 MessageEnvelope 中。
| 字段 | 类型 | 说明 |
|---|---|---|
msg_id |
uint64_t |
全局单调递增消息 ID |
timestamp_us |
uint64_t |
入队时间戳 (微秒,steady_clock) |
sender_id |
uint32_t |
发送者标识 |
priority |
MessagePriority |
消息优先级 |
template <typename PayloadVariant>
struct MessageEnvelope {
MessageHeader header;
PayloadVariant payload;
};消息信封,将消息头和有效载荷打包为一个传输单元。PayloadVariant 是 std::variant,承载具体消息类型。
enum class BackpressureLevel : uint8_t {
NORMAL = 0, // 队列水位 < 60%
WARNING = 1, // 队列水位 60%~80%
CRITICAL = 2, // 队列水位 80%~99%
FULL = 3 // 队列水位 >= 99%
};背压级别枚举,反映当前队列的拥塞状态。
| 级别 | 队列水位 | 行为 |
|---|---|---|
NORMAL |
< 60% | 所有优先级消息均可入队 |
WARNING |
60%~80% |
LOW 优先级消息被丢弃 |
CRITICAL |
80%~99% |
LOW + MEDIUM 优先级消息被丢弃 |
FULL |
>= 99% | 仅 HIGH 优先级有 1% 概率入队 |
enum class PerformanceMode : uint8_t {
FULL_FEATURED = 0, // 完整功能: 背压 + 统计 + 错误回调
BARE_METAL = 1, // 裸机模式: 仅核心入队/出队
NO_STATS = 2 // 无统计: 背压保留,关闭计数器
};运行时性能模式选择。
| 模式 | 背压 | 统计 | 错误回调 | 典型开销 |
|---|---|---|---|---|
FULL_FEATURED |
有 | 有 | 有 | ~38ns/msg |
BARE_METAL |
无 | 无 | 无 | ~30ns/msg |
NO_STATS |
有 | 无 | 有 | 介于两者之间 |
struct BusStatisticsSnapshot {
uint64_t total_published; // 累计发布消息数
uint64_t total_processed; // 累计处理消息数
uint64_t total_dropped; // 累计丢弃消息数
uint64_t total_backpressure_drops; // 背压丢弃数
uint64_t total_errors; // 累计错误数
uint64_t current_queue_size; // 当前队列深度
uint64_t peak_queue_size; // 峰值队列深度
uint64_t total_callbacks_invoked; // 累计回调调用次数
double avg_process_time_us; // 平均单批处理耗时 (微秒)
double queue_utilization; // 队列利用率 (0.0~1.0)
};总线运行时统计快照。仅在 FULL_FEATURED 模式下采集。
| 字段 | 类型 | 说明 |
|---|---|---|
total_published |
uint64_t |
从启动到现在累计发布的消息数 |
total_processed |
uint64_t |
累计被消费者处理的消息数 |
total_dropped |
uint64_t |
累计被丢弃的消息数 (含背压和队列满) |
total_backpressure_drops |
uint64_t |
因背压准入机制丢弃的消息数 |
total_errors |
uint64_t |
累计错误数 |
current_queue_size |
uint64_t |
当前环形缓冲中的消息数量 |
peak_queue_size |
uint64_t |
历史峰值队列深度 |
total_callbacks_invoked |
uint64_t |
累计触发的回调次数 |
avg_process_time_us |
double |
平均每次 ProcessBatch 调用的耗时 (微秒) |
queue_utilization |
double |
队列利用率,范围 0.0 ~ 1.0 |
固定容量字符串,栈上分配,无堆分配。适用于嵌入式场景下替代 std::string。
template <std::size_t N>
class FixedString;FixedString(); // 默认构造,空字符串
FixedString(const char* str); // 从 C 字符串构造,超长截断
FixedString(const char* str, std::size_t len); // 从缓冲区构造
FixedString(const std::string& str); // 从 std::string 构造标签类型,用于显式标记构造时允许截断。
static constexpr TruncateToCapacity_t TruncateToCapacity{};
FixedString(TruncateToCapacity_t, const char* str);const char* c_str() const noexcept;返回以 null 结尾的 C 字符串指针。
std::size_t size() const noexcept;返回当前字符串长度 (不含 null 终止符)。
固定容量向量,栈上分配,无堆分配。
template <typename T, std::size_t N>
class FixedVector;bool push_back(const T& value);
bool push_back(T&& value);追加元素到末尾。容量满时返回 false。
template <typename... Args>
bool emplace_back(Args&&... args);原地构造元素到末尾。容量满时返回 false。
void erase_unordered(std::size_t index);O(1) 无序删除: 将最后一个元素移动到被删除位置,然后缩减 size。不保持元素顺序。
-
参数:
index-- 要删除的元素索引 - 复杂度: O(1)
void clear() noexcept;清空所有元素,size 归零。不调用析构函数 (要求 T 为 trivially destructible 或由调用者管理)。
固定容量类型擦除可调用对象包装器,使用 SBO (Small Buffer Optimization) 内联存储。
template <typename Sig, std::size_t Cap = 64>
class FixedFunction;
// 偏特化
template <typename R, typename... Args, std::size_t Cap>
class FixedFunction<R(Args...), Cap>;-
模板参数:
-
Sig-- 函数签名,如void(int) -
Cap-- 内联缓冲区大小 (字节),默认 64
-
// 构造时 static_assert: sizeof(Callable) <= Cap
// 如果可调用对象超过内联缓冲区容量,编译失败当捕获体超过 Cap 字节时,static_assert 触发编译错误,避免运行时堆分配。
explicit operator bool() const noexcept;检查是否持有有效的可调用对象。
R operator()(Args... args) const;调用持有的可调用对象。未持有时行为未定义 (应先检查 operator bool)。
template <typename... Ts>
auto make_overloaded(Ts&&... ts);辅助函数,将多个 lambda/可调用对象组合为一个 overloaded visitor,用于 std::visit 分发。
用法示例:
auto visitor = make_overloaded(
[](const SensorData& d) { /* 处理传感器数据 */ },
[](const ControlCmd& c) { /* 处理控制命令 */ },
[](const auto&) { /* 默认处理 */ }
);
bus.ProcessBatchWith(visitor);运行时动态订阅组件基类。使用 std::weak_ptr 防止悬挂回调。
template <typename PayloadVariant>
class Component : public std::enable_shared_from_this<Component<PayloadVariant>>;template <typename T, typename Handler>
uint32_t SubscribeSafe(AsyncBus<PayloadVariant>& bus, Handler&& handler);安全订阅: 内部捕获 weak_ptr<Component>,回调触发时自动检查组件是否仍存活。如果组件已析构,回调静默跳过。
-
模板参数:
T-- 要订阅的消息类型 -
参数:
-
bus-- 总线引用 -
handler-- 消息处理函数
-
- 返回值: 订阅 ID
-
线程安全: 依赖
Subscribe()的写锁
template <typename T, typename Handler>
uint32_t SubscribeSimple(AsyncBus<PayloadVariant>& bus, Handler&& handler);简单订阅: 不使用 weak_ptr,由调用者保证组件生命周期覆盖订阅期。性能略优于 SubscribeSafe()。
编译期静态分发组件基类。使用 CRTP (Curiously Recurring Template Pattern) 实现零开销消息分发。
template <typename Derived, typename PayloadVariant>
class StaticComponent;auto MakeVisitor();生成 visitor 对象,自动将 PayloadVariant 中的每个类型路由到 Derived 类中对应的 void Handle(const T&) 方法。未提供 Handle 重载的类型将被静默忽略。
用法示例:
class MyComponent : public StaticComponent<MyComponent, MyPayload> {
public:
void Handle(const SensorData& data) { /* ... */ }
void Handle(const ControlCmd& cmd) { /* ... */ }
// StatusMsg 类型无 Handle,自动忽略
};
MyComponent comp;
bus.ProcessBatchWith(comp.MakeVisitor());template <typename D, typename T, typename = void>
struct HasHandler : std::false_type {};
template <typename D, typename T>
struct HasHandler<D, T, std::void_t<decltype(
std::declval<D>().Handle(std::declval<const T&>()))>>
: std::true_type {};编译期检测 Derived 类是否为类型 T 提供了 Handle(const T&) 方法。
-
HasHandler<MyComponent, SensorData>::value--true -
HasHandler<MyComponent, StatusMsg>::value--false
MakeVisitor() 内部使用此 trait 实现条件分发: 有 Handler 则调用,无则忽略。