美文网首页
百度 Apollo 8.0 Cyber 源代码分析(二)

百度 Apollo 8.0 Cyber 源代码分析(二)

作者: RonZheng2010 | 来源:发表于2024-11-24 10:28 被阅读0次

2 cyber的基本组件

2.1 Slot、Signal与Connection

Slot和Signal实现一对多的通知。

Slot保存一个回调函数。

  • 成员cb_保存这个回调函数,成员函数operator()会调用它。

Signal保存一个Slot实例的列表。

  • 成员函数Connect()创建一个Slot实例,并保存到slots_中。
  • 成员函数operator()遍历slots_,调用Slot实例的operator()。可以像调用函数一样调用它Signal的实例。

Connection保存Slot实例和它所属的Signal之间的关联关系。

  • slot_和signal_分别是Slot实例和Signal实例。

2.2 Blocker

Blocker包括两个先进先出队列:published_msg_queue_和observed_msg_queue_。

  • Publish()向published_msg_queue推入消息
  • Subcribe() 指定回调函数,从published_msg_queue_订阅消息,这些回调函数保存在成员published_callback_。
  • Observed()会将published_msg_queue_复制到observed_msg_queue_,这样读取时,就不需要加锁了。

2.3 CacheBuffer与ChannelBuffer

CacheBuffer是一个环形缓存,这是一个模板类,模板参数是元素类型。

  • 成员buffer_是一个vector,提供缓存空间。成员capacity_是可以保存的元素数量。
  • 成员函数Tail()/Head()/at()访问指定环形缓存的位置,成员函数Fetch()从指定位置取出元素。

关于ChannelBuffer,

  • 成员channel_id_ 是channel id。
  • 成员buffer_包括一个CacheBuffer实例。

2.4 DataNotifier / DataDispatcher / DataVisitor

DataNotifier负责消息到达的通知。

  • 成员notifies_map_是一个从channel_id到vector的映射,这个vector是一组回调函数。
  • 成员函数AddNotifier向指定channel的vector推入一个回调函数。
  • 成员函数则调用指定channel的vector中的所有回调函数,作为消息通知。

DataDispatcher负责向一组访问者派发消息。

  • 成员buffers_map_是一个从channel_id到vector的映射。这个vector是一组CacheBuffer实例,用于缓存收到的消息。
  • 成员notifier_ 是DataNotifier实例,用于通知访问者消息到达。
  • 成员函数AddBuffer()向成员bufers_map_中对应channel_id的vector,推送一个CacheBuffer实例。AddBuffer()的参数是一个ChannelBuffer实例,CacheBuffer实例从它获得。
  • Dispatch)派发消息。
    • 在对应channel_id的vector中的所有CacheBuffer实例,保存一个消息副本;
    • 通过成员notifier_ 通知这个channel的所有访问者。

DataVisitor打包了对DataDispatcher和DataNotifier的调用。它派生自DataVisitorBase。

关于DataVisitorBase,

  • 成员notifier_ 是一个回调函数,使用者通过成员函数RegisterNotifyCallback()设置。
  • 成员data_notifier_ 是唯一的DataNotifier实例。
  • 成员next_msg_index_ 是一个索引值,指向唤醒缓存CacheBuffer中的位置。

关于DataVisitor,

  • 每个DataVisitor实例从DataDispatcher监听/接收一个channel的消息。每个channel可以有多个DataVisitor实例接收。
  • 成员buffer_是一个ChannelBuffer实例。
  • 在DataVisitor的构造函数中,
    • 调用DataDispatcher::AddBuffer()加入自己的buffer_,这样当消息到达时,会在这里保存一份;
    • 调用DataNotifier::AddNotifier(),加入自己的notifier,这样就能得到消息通知。得到通知时,DataVisitorBase的成员notifier_会被调用。
  • 成员函数TryFetch()从next_msg_index_指定的环形缓存当前位置获取消息。

DataVisitor一般的使用流程是;

  • 指定channel创建DataVisitor实例,调用RegisterNotifyCallback()设置回调函数,假设名字为notifier。
  • 当这个channel有消息到达时,DataDispatcher会调用notifier。
  • 这时可以调用DataVisitor::TryFetch()得到消息。

相关链接

百度 Apollo 8.0 Cyber 源代码分析(一)
百度 Apollo 8.0 Cyber 源代码分析(二)
百度 Apollo 8.0 Cyber 源代码分析(三)
百度 Apollo 8.0 Cyber 源代码分析(四)
百度 Apollo 8.0 Cyber 源代码分析(五)

相关文章

网友评论

      本文标题:百度 Apollo 8.0 Cyber 源代码分析(二)

      本文链接:https://www.haomeiwen.com/subject/ofpzjjtx.html