将对象添加到侦听器队列时是否需要复制对象?

时间:2014-04-04 07:12:26

标签: c++ multithreading data-structures mutex

情况如下:

我处理通过套接字Connection收到的数据包,并且每个数据包都有一个不同的ID和一般类Message的关联子类(所以FooMessage,{{1 },BarMessage)。

我需要使用这些消息来更新程序中的一些信息(信息存储在不同的类中,例如HelloMessage涉及与AInformation有关的所有内容,A相关的事情到BInformation种类的东西,B等等......)。

为此,我引入了第三方:CInformation,它监听某些特定类型的消息,并使用它们来更新与Listener相关联的Information类。我们有Listener来处理AListenerFooMessage,有一些特定的函数可以更新BarMessageAInformation来处理BListener和{{1}并更新BarMessage ...

以下是通过套接字连接发出的HelloMessage的生命周期:

  1. BInformationMessage(字节数组)
  2. 中的DuhMessage创建
  3. ConnectionPacket发送给所有听众(我将解释我执行此步骤的问题,这对我来说是个问题
  4. 每个监听器都会查看DuhMessage,如果有兴趣更新监听器正在处理的信息类型,则消息由函数处理
  5. 第2步:

    为了处理步骤 2 ,我基本上在Connection中有一个DuhMessage列表(此列表必须是线程安全的,因为{{1}可以随时添加到Listener列表中。 Connection锁定列表并将Listener推送到所有Connection消息队列。 (Connection有一个消息队列,它一个接一个地消耗它们,更新DuhMessage类)

    这是我用Dia制作的模式,总结了它:

    enter image description here

    我的问题是:

    当我将Listener推送到Listener的队列时,我应该复制该对象吗?由于我的Information可能会尝试同时阅读DuhMessage的属性,他们不能吗?

    这是我为这种情况做的线程安全的deque实现(如果你可以验证它)。

    Listener

2 个答案:

答案 0 :(得分:1)

  1. 如果消息和侦听器之间存在一对一关联,则可以在单个thead中执行消息到侦听器限定,将消息移动到正确的侦听器,在这种情况下不会发生并发访问。
  2. 如果一条消息可以转到多个侦听器,则发送它们为“const DuhMessage *”,它们将无法以任何方式修改消息属性,因此并发读取访问将是安全的。 唯一的问题是谁将删除DuhMessage,使用ref_count等。

答案 1 :(得分:0)

最好的是破坏者模式(并行化管道)的变体。邮件的单个副本将提交给由固定大小的线程池支持的管道。

readonly侦听器的管道片段可以并行处理消息,如果需要,可以为自己使用创建可变副本(比如异步写入数据库)。

管道片段:readonly-> mutating,mutating-> mutating,mutating-> readonly必须进行序列化处理。

一旦所有侦听器/处理程序完成后,调度程序都应销毁原始消息。

复制事件处理程序的一部分将污染其逻辑并损害整个解决方案的可伸缩性。

相关问题