OMG Data Distribution Service(DDS)规范解读-Part5

2.4 Listeners, Conditions, and Wait-sets

Listeners和Conditions(和wait set相关)是两种允许APP知道DCPS有change的机制。

2.4.1 Communication Status

Communication Status是和Entity关联的,下表列出了所有Entity会有的status:
Communication Status以上的status可以被分为两类:

  • Read communication statuses:和data数据有关的,比如DATA_ON_READERS和DATA_AVAILABLE
  • Plain communication statuses:其他所有

Read communication statuses不会独立出现,也就是说,至少会有两个status会被同时改变,例如DATA_ON_READERS + DATA_AVAILABLE。这些改变(grouping)会被发给APP,如何操作取决于下面两种不同机制。
对于每一个Plain communication statuse来说,都会有相关的结构去控制相关的status的值。这些值与status的改变相关,也和这些status本身有关(例如,包含累积计数)。与下文解释的两种不同机制一起使用。

status value上图对应了不同的status里面包含的值及其数据类型。

2.4.2 Changes in Status

每个entity的communication status都关联一个StatusChangedFlag
此flag指示自上次APP“read”该状态以来,该特定通信状态是否发生了更改

2.4.2.1 Plain communication statuses

对于Plain communication statuses,StatusChangedFlag默认为FALSE,只有当状态改变才会设置为TRUE,并且当每次APP调用get_<plain communication status>接口时都会重置成FALSE。
changeflag每当调用关联的listener操作时,通信状态也被重置为FALSE,因为侦听器隐式访问作为参数传递给操作的状态。
此规则的一个例外是当关联的侦听器是’ nil ‘listener时。’ nil ‘时,线程认为是NOOP,并且’ nil '不会重置通信状态。

举例:
REQUESTED_DEADLINE_MISSED 的flag会变成TRUE,每当新的deadline发生的时候(也会增加total_count)。当调用get_requested_deadline_missed_status时,flag又会重置为FALSE。

2.4.2.2 Read Communication Statuses

对于Read Communication Statuses,StatusChangedFlag默认为FALSE。
StatusChangedFlag在data-sample到达或任何现有sample的ViewState, SampleState或InstanceState因任何原因而更改时变为TRUE,而不是调用DataReader::read, DataReader::take或它们的变体。

下面的事件会使得StatusChangedFlag变为TRUE:

  1. 新data的到来;
  2. InstanceState 的改变
    • 如DataWriter的OWNERSHIP QoS kind=EXLUSIVE,则通知实例已被拥有该实例的DataWriter处置;
    • 如DataWriter的OWNERSHIP QoS kind=SHARED,则通知实例已被任何DataWriter处置;
    • instance只有一个DataWriter,该DataWriter的liveliness已丢失;
    • 已知正在写入实例的唯一DataWriter unregistered实例的通知到达。

下面的事件会使得StatusChangedFlag变为FALSE:

  1. DATA_AVAILABLE 的StatusChangedFlag 变成FALSE:当相关的listener调用on_data_available或调用read/take操作;
  2. DATA_ON_READERS 的StatusChangedFlag 变成FALSE:
    • 当相关的listener调用on_data_on_readers;
    • on_data_available被DataReader所属的Sub调用;
    • read/take操作被调用

在这里插入图片描述

2.2.4.3 Access through Listeners

listener提供的是异步的通知,提供的接口如下图:
在这里插入图片描述

2.2.4.3.1 Listener Access to Plain Communication Status

  • 对于每一种communication status,都有一个对应的操作,命名方式是 on_<communication_status>,携带的参数是communication_status,如2.4.1 Communication Status表所示。
  • on_<communication_status> 可在相关实体以及嵌入该实体的实体上获得。
  • 当应用程序在实体上附加listener时,它必须设置一个掩码,该掩码指示中间件在该listener中启用哪些操作(参见操作entity::set_listener)。
  • 当Plain Communication Status发生变化时( StatusChangedFlag = True),中间件会触发启用的最“特定”的相关listener操作。如果这个相关的listener操作对应于应用程序设置的’ nil 'listener,则该操作将被视为由NO-OP操作处理。

2.2.4.3.2 Listener Access to Read Communication Status

与数据到达相关的两种状态的处理略有不同。由于它们构成了数据分发服务的真正目的,因此实际上不需要为普通通信状态提供默认机制,更重要的是,它们中的几个可能需要作为一个整体来处理,如2.2.4.1中所解释的那样。
规则是:每当read communication status有变化时:

  • 首先中间件会尝试触发 SubscriberListener的 on_data_on_readers 操作
  • 如果这没有作用(没有listener或无操作可用),会尝试触发DataReader的on_data_avilable操作
    其基本原理是,要么应用程序对数据到达之间的关系感兴趣,它就会使用第一个选项(然后通过在相关Subscriber上调用get_datareaders来获取相应的DataReader对象,然后通过调用返回的DataReader对象的read/take来获取数据),要么它想要完全独立地处理每个DataReader,它可以选择第二个选项(然后通过调用相关DataReader的read/take来获取数据)。
    注意,如果调用了on_data_on_readers,那么中间件将不会尝试调用on_data_available,但是,应用程序可以通过notify_datareaders操作强制调用具有数据的DataReader对象。
    在listeners调用中没有隐含的“事件队列”,也就是说,如果同一类型的多个状态更改顺序发生,则DCPS实现不必为每个“单元”更改交付一个listener回调。例如,可能会发生这样的情况,DCPS实现发现DataReader的liveliness发生了变化,因为出现了几个匹配的DataWriter实体;在这种情况下,只要提供给listener的LivelinessChangedStatus与最新的LivelinessChangedStatus相对应,DCPS实现就可以选择只调用一次DataReaderListener上的on_liveliness_changed操作。

2.2.4.4 Conditions and Wait-sets

conditions提供一种中间件能够与APP通信Communication Status改变的方式。

  1. APP会创建一些感兴趣的condition(StatusCondition,ReadCondition or QueryCondition),并将它们加到WaitSet中。
  2. 然后APP会wait,直到一个或多个condition的trigger_value变为TRUE。
  3. 获取trigger_value变为TRUE的condition的list,使用以下的操作:
    • 相关的Entity:get_status_changes 之后 get_<communication_status>。如果是一个StatusCondition和他状态的改变,参考plain communication status。
    • 相关的Subscriber:get_status_changes之后get_datareaders。如果是一个StatusCondition和他状态的改变,参考 DATA_ON_READERS(之后对DataReader进行read/take操作)。
    • 相关的DataReader:get_status_changes之后 read/take。如果是一个StatusCondition和他状态的改变,参考 DATA_AVAILABLE。
    • 相关的DataReader:如果是ReadCondition 或 QueryCondition,直接使用read_w_condition/take_w_condition。
      第一步create condition是在初始化的时候做的,其他都是在main loop中。

由于在等待返回时没有额外的信息从中间件传递到应用程序(只有触发的Condition对象列表),Condition对象意味着嵌入在启用时正确响应所需的所有信息。特别是,实体相关的条件只与一个实体相关,不能共享。
WaitSet的blocking操作的行为如下图:
在这里插入图片描述与listeners的调用类似,在唤醒WaitSet时没有隐含的“事件排队”,也就是说,如果附加到WaitSet的几个条件的trigger_value按顺序转换为TRUE,则DCPS实现只需要解除一次WaitSet的阻塞。
Condition/WaitSet机制的一个关键要点是设置每个Condition的trigger_value。

2.2.4.4.1 Trigger State of the StatusCondition

StatusCondition的trigger_value是其敏感的所有通信状态的ChangedStatusFlag的布尔或值。trigger_value==FALSE只在所有flag都为FALSE时才可能出现。
StatusCondition对特定通信状态的敏感性由set_enabled_statuses操作在条件上设置的enabled_statuses列表控制。

2.2.4.5 Trigger State of the ReadCondition

与StatusCondition意义,ReadCondition也有trigger_value,trigger_value决定着WaitSet的状态为BLOCKED 或 UNBLOCKED。然而,与StatusCondition不同的是,ReadCondition的trigger_value与至少存在一个由Service管理的样本相关联,其中SampleState、ViewState和InstanceState与ReadCondition的样本相匹配。此外,为了使QueryCondition具有trigger_value==TRUE,与sample相关联的数据必须使query_expression的计算结果为TRUE。
ReadCondition的trigger_value取决于相关DataReader上存在的样本,这意味着单个take()操作可能会改变几个ReadCondition或QueryCondition条件的trigger_value。例如,如果take了所有samples,那么之前与DataReader关联的任何ReadCondition和QueryCondition条件的trigger_value==TRUE将会看到trigger_value变为FALSE。注意,这并不能保证单独附加到这些条件的WaitSet对象不会被唤醒。一旦我们在可能唤醒附加的WaitSet的条件上设置了trigger_value==TRUE,那么将条件转换为trigger_value==FALSE并不一定会“唤醒”WaitSet,因为通常情况下“唤醒”可能是不可能的。结果是,阻塞在WaitSet上的应用程序可能会从等待返回一个条件列表,其中一些条件不再是“active”。如果多个线程并发地等待单独的WaitSet对象并获取与相同DataReader实体关联的数据,这是不可避免的。
为了进一步详细说明,请考虑以下示例:只要有新的样本到达,具有SAMPLE_STATE_MASK={NOT_READ}的ReadCondition就会有TRIGGER_VALUE为TRUE,并且只要所有新到达的样本都被read(因此它们的状态更改为READ)或take(它们不再由服务管理),ReadCondition就会转换为FALSE。 然而,如果相同的ReadCondition具有SAMPLE_STATE_MASK={READ,NOT_READ},则Trigger_Value只有在获取了所有新到达的样本后才会变为FALSE(只read它们是不够的,因为这只会将SampleState更改为READ,这与ReadCondition上的掩码重叠。

2.2.4.5.1 Trigger State of the GuardCondition

通过 set_trigger_value改变APP的行为.

2.2.4.6 Combination

这两种机制会组合使用。例如,使用WaitSet和Condition访问数据,并向listener发出错误通信状态的异步警告。
很可能应用程序将为每个特定的通信状态选择一种或另一种机制(而不是两种)。
但是,如果两种机制都启用,则首先使用侦听器机制,然后用信号通知WaitSet对象。

学习资料链接

  1. FastDDS相关介绍
  2. OpenDDS 监听器(Listeners)与条件(Conditions)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值