1. 事件数据访问(Accessing Event Data)
- GetNewSamples () 函数的作用
- 这是服务消费者在成功订阅事件后获取 Sample 的关键函数。它从通信管理(Communication Management,CM)缓冲区获取新数据,并通过回调函数提供给用户。
- 函数是一个模板函数,第一个参数是用户提供的回调函数,其签名必须是
void(ara::com::SamplePtr<SampleType const>)
,这种设计使得用户可以灵活地处理获取到的 Sample 数据。 - 第二个参数用于控制从 CM 中间件缓冲区中获取并反序列化后呈现给应用程序的 Sample 的最大数量。
- GetNewSamples () 的执行过程
- 执行时,
ara::com
实现会先检查应用程序持有的 Sample 数量是否超过之前订阅时承诺的最大数量,如果超过则返回错误码。 - 接着检查底层缓冲区是否有新的 Sample,如果有则进行反序列化并传递给回调函数
f
。这个过程会一直重复直到缓冲区没有新 Sample、达到用户提供的最大 Sample 数量限制或者超过订阅时承诺的最大 Sample 数量。
- 执行时,
2. 事件样本管理(Event Sample Management)
- SamplePtr 的语义
- 从
ara::com
实现传递到应用程序层的 SamplePtr 在语义上类似于独占指针std::unique_ptr
,所有权在传递时发生转移。 - 应用程序负责底层样本的生命周期管理,只要用户不销毁 SamplePtr 或显式调用赋值操作 / 修改器来释放 Sample,
ara::com
实现就不能回收 Sample 占用的内存槽。
- 从
- 内存槽分配和使用
- 存储事件样本数据的内存槽由
ara::com
实现分配,通常在调用 Subscribe () 时进行。应用程序通过参数maxSampleCount
定义可同时访问的最大事件数据样本数量。 - 在后续的 GetNewSamples () 调用中,
ara::com
实现会填充空闲的 "样本槽",并在应用程序的回调函数中传递指向它的 SamplePtr。 - 在回调函数中,应用程序设计者可以根据事件 Sample 数据的属性 / 值决定是否保留 SamplePtr,保留时是将其移动到外部作用域位置而不是复制(因为其行为类似于
std::unique_ptr
)。
- 存储事件样本数据的内存槽由
3. 示例中的体现
- 在
handleBrakeEventReception()
方法中,回调函数实现了简单的 SamplePtr 过滤,并将其移动到具有 "最近 N 个" 语义的全局存储中,这展示了如何在实际应用中根据具体需求对 SamplePtr 进行处理。
4. GetNewSamples () 函数的注意事项:
4.1 与订阅相关的方面
- 订阅数量的一致性
- 在调用 GetNewSamples () 函数之前,需确保已经正确地进行了订阅操作(Subscribe ()),并且要清楚在 Subscribe () 中设置的最大采样计数(maxSampleCount)。因为 GetNewSamples () 函数执行时会检查应用程序持有的 Sample 数量是否超过了 Subscribe () 中承诺的最大数量,如果超过可能导致返回错误码。
- 参数匹配
- 注意 GetNewSamples () 函数第二个参数 maxNumberOfSamples 的设置。这个参数控制从 CM 中间件缓冲区中获取并反序列化后呈现给应用程序的 Sample 的最大数量。应根据应用程序的处理能力和数据处理需求合理设置该参数,避免获取过多或过少的样本。
4.2 回调函数方面
- 回调函数的签名
- 提供给 GetNewSamples () 的回调函数必须满足特定的签名
void(ara::com::SamplePtr<SampleType const>)
,否则会导致编译错误或者运行时的异常行为。
- 提供给 GetNewSamples () 的回调函数必须满足特定的签名
- 内存管理
- 从 ara::com 实现传递到回调函数的 SamplePtr 是独占指针,在回调函数中处理 SamplePtr 时,要牢记其所有权转移的特性。如果需要保留样本以供后续使用,应在合适的外部作用域将 SamplePtr 移动(而不是复制),避免因不当操作导致内存泄漏或者样本过早被回收。
4.3 性能和资源方面
- 避免频繁调用导致的开销
- 不要在短时间内过于频繁地调用 GetNewSamples () 函数,尤其是在处理能力有限的系统中。频繁调用可能导致大量的反序列化操作和缓冲区检查操作,增加系统开销,影响系统性能。
- 资源占用控制
- 考虑到样本数据存储在由 ara::com 实现分配的内存槽中,且数量受 Subscribe () 中 maxSampleCount 的限制,要注意对样本的处理和存储,避免长时间保留大量不必要的样本,占用过多内存资源。