在这里插入图片描述

每日一句正能量

春会来,事会顺,人会好,花会开。
不是盲目乐观,而是相信时间、相信自然规律。冬天再长也会过去,困难再大也是阶段性的。与其焦虑,不如做好当下的事,然后等待。就像种花,你无法催促它,只能浇水松土,然后相信。


一、引言:当数据流淹没嵌入式系统

嵌入式系统正面临一个前所未有的挑战:数据生产速度远超处理能力。一个 6 轴 IMU 传感器以 1kHz 的频率输出数据,ADC DMA 以 10kHz 的速度填充缓冲区,CAN 总线以 500Kbps 的速率涌入报文,而主控 MCU 的主循环可能只能以 100Hz 的频率处理这些数据。

传统的应对方案是"轮询 + 中断 + 标志位":在中断里设置标志,主循环里检查标志并处理。这种模式的缺陷显而易见:

  • 中断里不能做太多事,否则影响实时性
  • 主循环可能错过数据,也可能被数据淹没
  • 多个数据源之间的协调靠全局变量和标志位,代码难以维护
  • 内存使用不可控,缓冲区要么溢出要么浪费

响应式编程(Reactive Programming)提供了一种全新的思路:将数据视为流(Stream),用声明式的方式描述数据从产生到消费的完整链路,并通过背压(Backpressure)机制让"慢消费者"控制"快生产者"的流速

本文将深入剖析 Reactive Streams 规范的核心原理,针对嵌入式资源受限场景进行轻量化实现,并给出完整的背压控制代码实践。


二、Reactive Streams 核心模型

2.1 四个核心接口

在这里插入图片描述

Reactive Streams 规范定义了四个核心接口,构成了异步非阻塞流处理的基石:

接口 职责 嵌入式映射
Publisher 数据生产者,负责生成并推送数据 传感器驱动、ADC DMA、串口接收
Subscriber 数据消费者,接收并处理数据 控制算法、日志记录、显示更新
Subscription 订阅关系,管理背压协商 流控决策器、缓冲区管理
Processor 既是 Publisher 又是 Subscriber,用于中间处理 滤波器、数据转换、合并操作

核心交互协议

Subscriber.subscribe(Publisher)     → 建立订阅关系
Publisher.onSubscribe(Subscription)  → 返回Subscription
Subscriber.request(n)                → 请求n个数据
Publisher.onNext(data)               → 推送数据
Subscriber.onComplete()              → 流结束
Subscriber.onError(error)            → 错误处理

背压的本质:Subscriber 通过 request(n) 主动告知 Publisher"我还能处理 n 个数据",Publisher 根据请求量推送数据。这种"拉-推混合模型"从根本上解决了生产者-消费者速率不匹配问题。

2.2 热流与冷流
  • 热流(Hot Observable):无论是否有订阅者,数据都会持续产生。如传感器采样、GPIO 中断。热流必须使用背压策略,否则必然溢出。
  • 冷流(Cold Observable):只有订阅后才开始产生数据。如文件读取、配置加载。冷流天然支持背压,因为生产由消费触发。

嵌入式场景中,绝大多数数据流都是热流——传感器不因为你的主循环忙就停止采样。


三、背压策略:四种武器

3.1 策略对比

在这里插入图片描述

策略 原理 数据丢失 内存风险 适用场景
BUFFER 数据缓存到缓冲区,消费者就绪后处理 高(可能OOM) 数据不可丢失,如日志、审计
DROP 丢弃无法处理的数据(最旧或最新) 实时性优先,如控制指令
LATEST 只保留最新数据,覆盖旧数据 有(旧数据) 极低(固定1个) 状态监控,如温度显示
THROTTLE 采样/节流,均匀降低数据速率 有(中间数据) 采样系统,如频谱分析
3.2 策略选择矩阵
/* backpressure_policy.h - 背压策略定义 */
#ifndef BACKPRESSURE_POLICY_H
#define BACKPRESSURE_POLICY_H

#include <stdint.h>

/* 背压策略类型 */
typedef enum {
    BP_BUFFER = 0,      /* 缓冲策略 */
    BP_DROP_OLDEST,      /* 丢弃最旧 */
    BP_DROP_LATEST,      /* 丢弃最新 */
    BP_LATEST_ONLY,      /* 只保留最新 */
    BP_THROTTLE_SAMPLE,  /* 采样节流 */
    BP_THROTTLE_DEBOUNCE,/* 防抖节流 */
    BP_ERROR             /* 错误策略:溢出时报错 */
    } BackpressurePolicy_t;

/* 策略配置 */
typedef struct {
    BackpressurePolicy_t policy;
    uint16_t buffer_size;       /* 缓冲区大小 */
     uint16_t high_watermark;    /* 高水位线 (%) */
     uint16_t low_watermark;     /* 低水位线 (%) */
     uint32_t throttle_interval_ms; /* 节流间隔 */
     } BackpressureConfig_t;

/* 策略选择建议 */
static inline BackpressurePolicy_t SelectPolicyForScenario(uint8_t scenario) {
    switch (scenario) {
            case SCENARIO_SENSOR_LOG:      return BP_BUFFER;           /* 传感器日志不可丢失 */
            case SCENARIO_REALTIME_CTRL:   return BP_LATEST_ONLY;      /* 控制指令只要最新 */
             case SCENARIO_STATUS_MONITOR:  return BP_LATEST_ONLY;      /* 状态显示只要最新 */
             case SCENARIO_AUDIO_STREAM:    return BP_BUFFER;           /* 音频流需完整 */
             case SCENARIO_KEY_EVENT:       return BP_DROP_OLDEST;      /* 按键事件可丢弃旧 */
             case SCENARIO_CAN_BUS:         return BP_THROTTLE_SAMPLE;  /* CAN报文采样 */
             default:                       return BP_DROP_LATEST;
                 }
                 }

#endif

四、嵌入式 Reactive Streams 实现

4.1 整体架构

在这里插入图片描述

嵌入式 Reactive Streams 实现分为三层:

Publisher 层:将硬件数据源封装为 Publisher

  • AdcPublisher:ADC DMA 完成中断触发数据推送
  • GpioPublisher:GPIO 中断触发事件推送
  • UartPublisher:串口接收中断触发数据推送
  • TimerPublisher:定时器周期性触发
  • CanPublisher:CAN 接收中断触发报文推送

Processor 层:流处理操作符

  • Filter:数字滤波(低通、高通、卡尔曼)
  • Map:数据转换(原始值→物理量)
  • Buffer:批量缓冲(凑够 N 个一起处理)
  • Merge:多流合并
  • Window:滑动窗口(用于 FFT、统计分析)

Subscriber 层:数据消费者

  • MotorController:电机控制算法
  • DisplayUpdater:显示刷新
  • Logger:日志记录
  • CloudUploader:云端上传
4.2 核心实现
/* reactive_streams.h - 嵌入式Reactive Streams核心接口 */
#ifndef REACTIVE_STREAMS_H
#define REACTIVE_STREAMS_H

#include <stdint.h>
#include <stdbool.h>

/* 前向声明 */
struct Subscription;
struct Publisher;
struct Subscriber;
/* 数据项 */
typedef struct {
void* data;
uint16_t len;
uint32_t timestamp;
uint32_t seq;
} StreamItem_t;
/* Subscription接口 */
typedef struct Subscription {
    void (*request)(struct Subscription* self, uint32_t n);
    void (*cancel)(struct Subscription* self);
    /* 私有数据 */
    uint32_t requested_count;   /* 已请求未消费的数量 */
    uint32_t delivered_count;   /* 已推送的数量 */
    bool cancelled;
        void* private_data;
        } Subscription_t;
        /* Subscriber接口 */
        typedef struct Subscriber {
            void (*onSubscribe)(struct Subscriber* self, Subscription_t* subscription);
            void (*onNext)(struct Subscriber* self, const StreamItem_t* item);
            void (*onError)(struct Subscriber* self, int error_code);
            void (*onComplete)(struct Subscriber* self);
            /* 私有数据 */
            Subscription_t* subscription;
            void* private_data;
            } Subscriber_t;
            /* Publisher接口 */
            typedef struct Publisher {
            void (*subscribe)(struct Publisher* self, Subscriber_t* subscriber);
            /* 私有数据 */
            Subscriber_t* subscriber;
            Subscription_t subscription;
            void* private_data;
            } Publisher_t;
            /* Processor:既是Publisher又是Subscriber */
            typedef struct Processor {
            Publisher_t publisher;
            Subscriber_t subscriber;
            void* private_data;
            } Processor_t;
            /* 内存池节点 */
            typedef struct StreamNode {
            StreamItem_t item;
            struct StreamNode* next;
            bool in_use;
            } StreamNode_t;
            /* 流管理器 */
            typedef struct {
            StreamNode_t* pool;         /* 预分配节点池 */
            uint16_t pool_size;
            uint16_t pool_used;
            StreamNode_t* head;         /* 链表头 *
            StreamNode_t* tail;         /* 链表尾 */
            uint16_t queue_depth;       /* 当前队列深度 */
            BackpressureConfig_t bp_config;
            uint16_t high_watermark_count;
            uint16_t low_watermark_count;
            } StreamManager_t;
            /* API */
            int ReactiveStreams_Init(StreamManager_t* mgr, uint16_t pool_size, 
								const BackpressureConfig_t* config);\nStreamNode_t* 					
								StreamManager_AllocNode(StreamManager_t* mgr);
								void StreamManager_FreeNode(StreamManager_t* mgr, StreamNode_t* node);
								int StreamManager_Enqueue(StreamManager_t* mgr, const StreamItem_t* item);
								int StreamManager_Dequeue(StreamManager_t* mgr, StreamItem_t* item);
								uint16_t StreamManager_GetDepth(const StreamManager_t* mgr);
								void StreamManager_ApplyBackpressure(StreamManager_t* mgr);
								#endif
/* reactive_streams.c - 核心实现 */
#include \"reactive_streams.h\"
#include <string.h>
/* 初始化流管理器 */
int ReactiveStreams_Init(StreamManager_t* mgr, uint16_t pool_size,
const BackpressureConfig_t* config) {
if (!mgr || !config || pool_size == 0) return -EINVAL;
memset(mgr, 0, sizeof(StreamManager_t));
/* 预分配节点池(避免运行时malloc) */
mgr->pool = (StreamNode_t*)malloc(sizeof(StreamNode_t) * pool_size);
if (!mgr->pool) return -ENOMEM;
memset(mgr->pool, 0, sizeof(StreamNode_t) * pool_size);
mgr->pool_size = pool_size;
mgr->pool_used = 0;
/* 初始化空闲链表 */
for (uint16_t i = 0; i < pool_size - 1; i++) {
mgr->pool[i].next = &mgr->pool[i + 1];
 }
  mgr->pool[pool_size - 1].next = NULL;
   /* 配置背压 */
   memcpy(&mgr->bp_config, config, sizeof(BackpressureConfig_t));
   mgr->high_watermark_count = (pool_size * config->high_watermark) / 100;
   mgr->low_watermark_count = (pool_size * config->low_watermark) / 100;
   Log_Info(\"ReactiveStreams initialized: pool=%u, hwm=%u, lwm=%u\",
   pool_size, mgr->high_watermark_count, mgr->low_watermark_count);
   return 0;
   }
   /* 分配节点 */
   StreamNode_t* StreamManager_AllocNode(StreamManager_t* mgr) {
   if (!mgr || mgr->pool_used >= mgr->pool_size) return NULL;
   /* 从空闲链表取一个节点 */
   StreamNode_t* node = mgr->pool;
   if (!node) return NULL;
   mgr->pool = node->next;
   node->next = NULL;
   node->in_use = true;
   mgr->pool_used++;
    return node;
    }
    /* 释放节点 */
    void StreamManager_FreeNode(StreamManager_t* mgr, StreamNode_t* node) {
    if (!mgr || !node) return;
    node->in_use = false;
    node->next = mgr->pool;
    mgr->pool = node;
    mgr->pool_used--;
    }
    /* 入队(Publisher调用) */
    int StreamManager_Enqueue(StreamManager_t* mgr, const StreamItem_t* item) {
    if (!mgr || !item) return -EINVAL;
    /* 检查背压状态 */
    if (mgr->queue_depth >= mgr->high_watermark_count) {
    /* 触发背压策略 */
    StreamManager_ApplyBackpressure(mgr);
     /* 如果策略是ERROR,直接返回 */
     if (mgr->bp_config.policy == BP_ERROR) {
     Log_Error(\"Stream overflow, dropping item\");
     return -EAGAIN;
     }
     }
     /* 分配节点 */
     StreamNode_t* node = StreamManager_AllocNode(mgr);
     if (!node) {
     /* 节点池耗尽,根据策略处理 */
     switch (mgr->bp_config.policy) {
     case BP_DROP_OLDEST:
     /* 丢弃最旧数据,腾出空间 */
     if (mgr->head) {
     StreamNode_t* old = mgr->head;
     mgr->head = old->next;
     if (!mgr->head) mgr->tail = NULL;
     StreamManager_FreeNode(mgr, old);
     mgr->queue_depth--;
     /* 重新分配 */
     node = StreamManager_AllocNode(mgr);
     }
     break;
     case BP_DROP_LATEST:
     /* 直接丢弃最新数据 */
     Log_Warn(\"Stream full, dropping latest item\");
     return -EAGAIN;
     case BP_LATEST_ONLY:
     /* 覆盖最后一个节点 */
     if (mgr->tail) {
     memcpy(&mgr->tail->item, item, sizeof(StreamItem_t));
      return 0;
      }
      break;
      default:
      return -ENOMEM;
      }
      }
      if (!node) return -ENOMEM;
      /* 复制数据 */
      memcpy(&node->item, item, sizeof(StreamItem_t));
      ode->next = NULL;
      /* 加入队列尾部 */
      if (mgr->tail) {
      mgr->tail->next = node;
      } else {
      mgr->head = node;
      }
      mgr->tail = node;
      mgr->queue_depth++;
      return 0;
      }
      /* 出队(Subscriber调用) */
      int StreamManager_Dequeue(StreamManager_t* mgr, StreamItem_t* item) {
      if (!mgr || !item) return -EINVAL;
      if (!mgr->head) return -EAGAIN;  /* 队列为空 */
      StreamNode_t* node = mgr->head;
      mgr->head = node->next;
      if (!mgr->head) mgr->tail = NULL;
      memcpy(item, &node->item, sizeof(StreamItem_t));
      StreamManager_FreeNode(mgr, node);
       mgr->queue_depth--;
        return 0;
        }
        /* 应用背压策略 */
        void StreamManager_ApplyBackpressure(StreamManager_t* mgr) {
        if (!mgr) return;
        switch (mgr->bp_config.policy) {
        case BP_THROTTLE_SAMPLE:
        /* 通知Publisher降低采样率 */
        Publisher_Throttle(mgr, true);
        break;
        case BP_BUFFER:
        /* 缓冲区策略:如果已满则扩展(嵌入式不推荐)或报错 */
        if (mgr->queue_depth >= mgr->pool_size) {
         Log_Error(\"Buffer full, consider increasing pool size\");
         }
         break;
         case BP_LATEST_ONLY:
         /* 不需要特殊处理,入队时会自动覆盖 */
         break;
         default:
         break;
         }
          /* 发布背压事件 */
          if (mgr->queue_depth >= mgr->high_watermark_count) {
          EventBus_Publish(EVENT_BACKPRESSURE_HIGH, mgr->queue_depth);
          }
          }
          /* 获取队列深度 */
          uint16_t StreamManager_GetDepth(const StreamManager_t* mgr) {
           return mgr ? mgr->queue_depth : 0;
           }

五、传感器数据流背压控制实践

5.1 完整数据链路

在这里插入图片描述

以 1kHz 采样率的温度传感器为例,展示完整的背压控制链路:

/* sensor_publisher.c - 传感器Publisher实现 */
#include \"reactive_streams.h\"
/* 传感器Publisher上下文 */
typedef struct {
Publisher_t base;
uint8_t sensor_id;
uint32_t sample_rate_hz;
 uint32_t throttle_rate_hz;
 bool throttled;
 TimerHandle_t sample_timer;
 StreamManager_t* stream_mgr;
 } SensorPublisher_t;
 /* ADC采样完成中断 */
 static void OnAdcConversionComplete(ADC_HandleTypeDef* hadc) {
 SensorPublisher_t* pub = GetPublisherFromAdc(hadc);
 if (!pub) return;
  /* 读取ADC值 */
  uint16_t adc_raw = HAL_ADC_GetValue(hadc);
   /* 构建数据项 */
   static uint8_t data_buffer[4];
   memcpy(data_buffer, &adc_raw, sizeof(adc_raw));
   StreamItem_t item = {
   .data = data_buffer,
    .len = sizeof(adc_raw),
    .timestamp = HAL_GetTick(),
    .seq = pub->base.subscription.delivered_count++
    };
    /* 入队(可能触发背压) */
    int ret = StreamManager_Enqueue(pub->stream_mgr, &item);
    if (ret != 0) {
    /* 背压触发,记录统计 */
    g_backpressureStats.dropped_count++;
    }
    /* 检查是否需要启动下一次转换 */
    if (!pub->throttled) {
    HAL_ADC_Start_IT(hadc);
    }
    }
    /* Publisher订阅实现 */
    static void SensorPublisher_Subscribe(Publisher_t* self, Subscriber_t* subscriber) {
    SensorPublisher_t* pub = (SensorPublisher_t*)self;
    self->subscriber = subscriber;
    /* 创建Subscription */
    self->subscription.requested_count = 0;
    self->subscription.delivered_count = 0;
    self->subscription.cancelled = false;
    self->subscription.request = SensorSubscription_Request;
    self->subscription.cancel = SensorSubscription_Cancel;
    self->subscription.private_data = pub;
    /* 通知Subscriber */
    if (subscriber->onSubscribe) {
    subscriber->onSubscribe(subscriber, &self->subscription);
    }
    Log_Info(\"SensorPublisher %u subscribed\", pub->sensor_id);
    }
    /* Subscription.request实现 */
    static void SensorSubscription_Request(Subscription_t* self, uint32_t n) {
    SensorPublisher_t* pub = (SensorPublisher_t*)self->private_data;
    self->requested_count += n;
    /* 根据请求量调整采样率 */
    if (self->requested_count > 20) {
    /* 消费者处理能力强,可以全速采样 */
    pub->throttled = false;
    pub->sample_rate_hz = 1000;
    } else if (self->requested_count > 10) {
    /* 中等处理能力 */
    pub->throttled = false;
    pub->sample_rate_hz = 500;
    } else {
    /* 处理能力弱,节流 */
    pub->throttled = true;
    pub->sample_rate_hz = 100;
    }
    /* 重新配置定时器 */
    uint32_t period_ms = 1000 / pub->sample_rate_hz;
    osTimerStop(pub->sample_timer);
    osTimerStart(pub->sample_timer, period_ms);
    Log_Debug(\"Sensor %u: request(%u), rate=%uHz\", pub->sensor_id, n, pub->sample_rate_hz);
    }
    /* 创建传感器Publisher */
    SensorPublisher_t* SensorPublisher_Create(uint8_t sensor_id, ADC_HandleTypeDef* hadc,
    StreamManager_t* stream_mgr) {
    SensorPublisher_t* pub = (SensorPublisher_t*)malloc(sizeof(SensorPublisher_t));
    if (!pub) return NULL;
    memset(pub, 0, sizeof(SensorPublisher_t));
    pub->sensor_id = sensor_id;
    pub->sample_rate_hz = 1000;
    pub->throttle_rate_hz = 100;
    pub->throttled = false;
    pub->stream_mgr = stream_mgr;
    pub->base.subscribe = SensorPublisher_Subscribe;
    pub->base.private_data = pub;
    /* 创建采样定时器 */
    pub->sample_timer = osTimerNew(SensorPublisher_OnTimer, osTimerPeriodic, pub, NULL);
    /* 注册ADC中断回调 */
    RegisterAdcCallback(hadc, OnAdcConversionComplete);
    return pub;
    }
/* filter_processor.c - 滤波Processor实现 */
#include \"reactive_streams.h\"
/* 卡尔曼滤波Processor */
typedef struct {
Processor_t base;
/* 卡尔曼滤波参数 */
float q;           /* 过程噪声 */
float r;           /* 测量噪声 */
float x;           /* 估计值 */
float p;           /* 估计误差协方差 */
float k;           /* 卡尔曼增益 */
uint32_t process_count;
} KalmanFilterProcessor_t;
/* Subscriber接口:接收上游数据 */
static void KalmanFilter_OnNext(Subscriber_t* self, const StreamItem_t* item) {
KalmanFilterProcessor_t* proc = (KalmanFilterProcessor_t*)self->private_data;
 /* 解析输入数据 */
 uint16_t raw_adc = *(uint16_t*)item->data;
 float measurement = AdcToTemperature(raw_adc);  /* ADC值转温度 */
 /* 卡尔曼滤波 */
 /* 预测 */
 proc->p = proc->p + proc->q;
 /* 更新 */
 proc->k = proc->p / (proc->p + proc->r);
 proc->x = proc->x + proc->k * (measurement - proc->x);
 proc->p = (1 - proc->k) * proc->p;
 proc->process_count++;
 /* 构建输出数据 */
 static float filtered_temp;
 filtered_temp = proc->x;
 StreamItem_t output = {
 .data = &filtered_temp,
 .len = sizeof(filtered_temp),
 .timestamp = item->timestamp,
 .seq = item->seq
 };
 /* 推送给下游Subscriber */
 if (proc->base.publisher.subscriber && 
 proc->base.publisher.subscriber->onNext) {
 proc->base.publisher.subscriber->onNext(
  proc->base.publisher.subscriber, &output);
  }
  }
  /* Publisher接口:订阅下游 */
  static void KalmanFilter_Subscribe(Publisher_t* self, Subscriber_t* subscriber) {
  KalmanFilterProcessor_t* proc = (KalmanFilterProcessor_t*)self->private_data;
  self->subscriber = subscriber;
  self->subscription.request = KalmanFilter_Request;
  self->subscription.cancel = KalmanFilter_Cancel;
  self->subscription.private_data = proc;
  if (subscriber->onSubscribe) {
  subscriber->onSubscribe(subscriber, &self->subscription);
  }
  }
  /* 创建卡尔曼滤波Processor */
  KalmanFilterProcessor_t* KalmanFilterProcessor_Create(float q, float r) {
  KalmanFilterProcessor_t* proc = (KalmanFilterProcessor_t*)malloc(sizeof(KalmanFilterProcessor_t));
  if (!proc) return NULL;
  memset(proc, 0, sizeof(KalmanFilterProcessor_t));
   proc->q = q;
   proc->r = r;\
   proc->x = 25.0f;  /* 初始温度估计 */
   proc->p = 1.0f;
   /* 初始化Subscriber接口 */
   proc->base.subscriber.onNext = KalmanFilter_OnNext;
   proc->base.subscriber.onError = KalmanFilter_OnError;
   proc->base.subscriber.onComplete = KalmanFilter_OnComplete;
   proc->base.subscriber.private_data = proc;
   /* 初始化Publisher接口 */
    proc->base.publisher.subscribe = KalmanFilter_Subscribe;
    proc->base.publisher.private_data = proc;
    return proc;
    }

六、多流合并与背压协调

6.1 合并策略

在这里插入图片描述

嵌入式场景中经常需要合并多个传感器数据流:

/* merge_processor.c - 多流合并Processor */
#include \"reactive_streams.h\"
/* 合并模式 */
typedef enum {
MERGE_MODE_ZIP = 0,           /* 同步对齐:等待所有流同序号数据 */
MERGE_MODE_COMBINE_LATEST,    /* 最新值:任一更新即触发 */
MERGE_MODE_MERGE              /* 交错合并:保持时序 */
} MergeMode_t;
/* 合并Processor上下文 */
typedef struct {
Processor_t base;
MergeMode_t mode;
/* 输入流 */
#define MAX_INPUT_STREAMS 4
struct {
Subscriber_t subscriber;   /* 作为Subscriber接收上游 */
StreamItem_t latest_item;
bool has_data;
uint32_t last_seq;
} inputs[MAX_INPUT_STREAMS];
uint8_t input_count;
/* 同步对齐缓冲区(Zip模式) */
StreamItem_t zip_buffer[MAX_INPUT_STREAMS];
uint32_t zip_target_seq;
/* 输出 */
Publisher_t* output_pub;
} MergeProcessor_t;
/* 输入流Subscriber的onNext */
static void MergeInput_OnNext(Subscriber_t* self, const StreamItem_t* item) {
/* 找到对应的输入槽 */
MergeProcessor_t* proc = NULL;
uint8_t input_idx = 0;
for (uint8_t i = 0; i < MAX_INPUT_STREAMS; i++) {
if (&proc->inputs[i].subscriber == self) {
 proc = (MergeProcessor_t*)self->private_data;
  input_idx = i;
  break;
  }
   }
   if (!proc) return;
   switch (proc->mode) {
   case MERGE_MODE_COMBINE_LATEST:
   /* 更新最新值并立即触发 */
   memcpy(&proc->inputs[input_idx].latest_item, item, sizeof(StreamItem_t));
    proc->inputs[input_idx].has_data = true;
    MergeProcessor_CombineLatest(proc);
    break;
    case MERGE_MODE_ZIP:
    /* 缓存数据,等待所有流对齐 */
     if (item->seq == proc->zip_target_seq) {
      memcpy(&proc->zip_buffer[input_idx], item, sizeof(StreamItem_t));
      proc->inputs[input_idx].has_data = true;
      MergeProcessor_CheckZipComplete(proc);
      }
      break;
      case MERGE_MODE_MERGE:
       /* 直接转发,保持时序 */
       MergeProcessor_Forward(proc, item);
        break;
        }
        }
        /* CombineLatest:合并各流最新值 */
        static void MergeProcessor_CombineLatest(MergeProcessor_t* proc) {
        /* 检查是否所有流都有数据 */
        for (uint8_t i = 0; i < proc->input_count; i++) {
        if (!proc->inputs[i].has_data) return;
        }
        /* 构建合并数据包 */
        static EnvDataPacket_t packet;
        packet.temp = *(float*)proc->inputs[0].latest_item.data;
        packet.humidity = *(uint16_t*)proc->inputs[1].latest_item.data;
        packet.pressure = *(uint32_t*)proc->inputs[2].latest_item.data;
        packet.timestamp = HAL_GetTick();
        StreamItem_t output = {
        .data = &packet,
        .len = sizeof(packet),
        .timestamp = packet.timestamp,
        .seq = proc->inputs[0].latest_item.seq
        };
        /* 推送给下游 */
        if (proc->base.publisher.subscriber && 
        proc->base.publisher.subscriber->onNext) {
        proc->base.publisher.subscriber->onNext(
        proc->base.publisher.subscriber, &output);
         }
         }
         /* 背压协调:取最慢流速 */
         static void MergeProcessor_CoordinateBackpressure(MergeProcessor_t* proc) {
         /* 找到最小的request_count */
         uint32_t min_request = 0xFFFFFFFF;
         for (uint8_t i = 0; i < proc->input_count; i++) {
         if (proc->inputs[i].subscriber.subscription &&
         proc->inputs[i].subscriber.subscription->requested_count < min_request) {
            min_request = proc->inputs[i].subscriber.subscription->requested_count;
              }
              }
              /* 向上游传播背压 */
              for (uint8_t i = 0; i < proc->input_count; i++) {
              if (proc->inputs[i].subscriber.subscription) {
              proc->inputs[i].subscriber.subscription->requested_count = min_request;
               }
               }\
                Log_Debug(\"Merge backpressure coordinated: min_request=%u\", min_request);
                }

七、HarmonyOS 集成:分布式流处理

在 HarmonyOS 分布式场景中,Reactive Streams 可以跨设备运行:

/* harmonyos_distributed_stream.c */
#include \"softbus_bus_center.h\"
#include \"reactive_streams.h\"
/* 分布式Publisher:将本地数据流发布到网络 */
typedef struct {
Publisher_t base;
char peer_device_id[64];
char channel_name[32];
StreamManager_t* local_mgr;
} DistributedPublisher_t;
/* 本地数据入队时,同时发送到远端 */
static int DistributedPublisher_Enqueue(DistributedPublisher_t* pub, 
      const StreamItem_t* item) {
      /* 本地入队 */
      int ret = StreamManager_Enqueue(pub->local_mgr, item);
      if (ret != 0) return ret;\
      /* 序列化并发送到远端 */
      uint8_t serialized[256];
      uint16_t len = SerializeStreamItem(item, serialized, sizeof(serialized));
      SoftBusMessage_t msg = {
      .type = SOFTBUS_MSG_TYPE_DATA,
      .channel = pub->channel_name,
      .payload = serialized,
      .payloadLen = len
      };
      return SoftBus_SendMessage(pub->peer_device_id, &msg, NULL, 0);
      }
      /* 分布式Subscriber:接收远端数据流 */
      typedef struct {
      Subscriber_t base;
      char local_channel[32];
      StreamManager_t* recv_mgr;
      } DistributedSubscriber_t;
      /* 收到远端数据 */
      static void OnDistributedDataReceived(const char* from_device, 
             const SoftBusMessage_t* msg) {
             DistributedSubscriber_t* sub = FindSubscriberByChannel(msg->channel);
             if (!sub) return;
             /* 反序列化 */
             StreamItem_t item;
             DeserializeStreamItem(msg->payload, msg->payloadLen, &item);
             /* 入队 */
             StreamManager_Enqueue(sub->recv_mgr, &item);
             /* 触发本地处理 */
             if (sub->base.onNext) {
             sub->base.onNext(&sub->base, &item);
             }
             }
             /* 跨设备背压控制 */
             static void DistributedBackpressure_Control(DistributedPublisher_t* pub,
                       uint32_t remote_capacity) {
                       /* 根据远端处理能力调整本地发送速率 */
                       if (remote_capacity < 5) {
                       /* 远端处理能力弱,大幅降低采样率 */
                       SensorPublisher_Throttle(pub->local_pub, true, 0.1f);
                       } else if (remote_capacity < 20) {
                       /* 中等能力 */
                       SensorPublisher_Throttle(pub->local_pub, true, 0.5f);
                       } else {
                       /* 能力强,全速 */
                       SensorPublisher_Throttle(pub->local_pub, false, 1.0f);
                       }
                       }

八、性能对比与优化

8.1 Reactive Streams vs 传统轮询

在这里插入图片描述

指标 传统轮询 Reactive Streams 说明
实时性 4 9 中断驱动,数据到达立即处理
CPU效率 3 9 无空转,按需处理
内存效率 5 7 预分配节点池,可控可预测
代码清晰度 6 8 声明式流处理,逻辑清晰
可扩展性 4 9 新增Processor即可扩展功能
资源可控性 5 9 背压机制确保资源不溢出
8.2 关键优化手段
/* 优化1:零拷贝数据传输 */
typedef struct {
/* 不复制数据,只传递指针 */
void* data_ptr;
uint16_t len;
bool owns_data;  /* 是否拥有数据所有权 */
} ZeroCopyItem_t;
/* 优化2:批量处理减少中断频率 */
#define BATCH_SIZE 10
static void ProcessBatch(Subscriber_t* sub, StreamManager_t* mgr) {
StreamItem_t batch[BATCH_SIZE];
uint8_t count = 0;
/* 一次性取出多个数据 */
while (count < BATCH_SIZE && StreamManager_Dequeue(mgr, &batch[count]) == 0) {
count++;
}
/* 批量处理 */
if (sub->onBatch) {
sub->onBatch(sub, batch, count);
}
}
/* 优化3:内存对齐与缓存友好 */
typedef struct __attribute__((aligned(4))) {
float data[4];      /* 4通道传感器数据 */
uint32_t timestamp;
uint16_t seq;
uint16_t flags;
} AlignedStreamItem_t;  /* 24字节,缓存行对齐 */
/* 优化4:编译期确定流拓扑 */
#ifdef STATIC_STREAM_TOPOLOGY
/* 编译期确定Publisher、Processor、Subscriber关系 */
/* 避免运行时动态分配和查找 */
static const StreamTopology_t g_topology = {
.publisher = &g_adcPublisher,
.processors = {&g_kalmanFilter, &g_movingAverage},
.subscriber = &g_motorController
};
#endif

九、总结

响应式编程不是"大后端"的专利,在嵌入式系统中同样具有巨大价值:

  1. Reactive Streams 规范提供了 Publisher-Subscriber-Subscription 的标准模型,通过 request(n) 实现背压控制
  2. 四种背压策略(BUFFER/DROP/LATEST/THROTTLE)适配不同场景,嵌入式推荐 LATEST 和 THROTTLE
  3. 内存池预分配避免了运行时动态分配的碎片和失败风险
  4. Processor 链式处理让数据流处理像搭积木一样组合
  5. HarmonyOS 分布式扩展让流处理跨越设备边界,实现真正的分布式响应式系统

在 HarmonyOS 生态中,随着设备类型从单一 MCU 扩展到分布式多终端协同,Reactive Streams 提供的声明式、背压感知的流处理能力,将成为连接"海量数据"与"有限资源"的关键桥梁。


转载自:https://blog.csdn.net/u014727709/article/details/162631551
欢迎 👍点赞✍评论⭐收藏,欢迎指正

Logo

讨论HarmonyOS开发技术,专注于API与组件、DevEco Studio、测试、元服务和应用上架分发等。

更多推荐