【问题标题】:How a consumer posts back to the same Disruptor ring buffer消费者如何回发到同一个 Disruptor 环形缓冲区
【发布时间】:2015-01-05 04:38:11
【问题描述】:

在多生产者设置中,有一个生产者线程和一个消费者线程。消费者可以将新事件发布回同一个环形缓冲区吗?我假设它在缓冲区已满时中断,并且消费者线程在处理当前事件时永远不会获得空闲插槽。换句话说,死锁发生了。

最好的方法是什么?我是否必须引入一种代理线程来接收来自消费者的事件并将它们像普通生产者一样发布到环形缓冲区?

补充 - 为什么有用? 假设消费者线程正在处理股票市场数据事件,它需要向市场模拟器(一个类)发送订单,理想情况下,市场模拟器应该向同一个环形缓冲区发送订单执行事件。

【问题讨论】:

  • 除了最简单的形式之外,就不能有多个生产者吗?如果是这样,消费者很可能是生产者,对吧?警告:我唯一接触过这种模式的是 Martin Fowler 的一篇文章。
  • 生产者不能超过一个吗? -> 是 /*SPACE */ 如果是这样,消费者很可能是生产者,对吧? -> 不,不确定原因。想想如果一个线程在持有锁的情况下尝试获取锁会发生什么。

标签: disruptor-pattern


【解决方案1】:

根据问题的其他细节提供单独的答案(我仍然相信我的原始答案是有效的)。

在我的头脑/经验中,您试图一次性做很多事情,因为您将环形缓冲区的消费者和发布者混为一谈,这通常是独立的关注点。我通常希望您的模拟器的响应事件以与其处理原始事件相同的方式传递到环形缓冲区。

话虽如此,您所要求的实际上是可能的。

但是,您必须自己做更多的工作并编写自定义EventProcessor,这将允许您在尝试发布事件之前将传入消息标记为已处理(从而释放槽)。

【讨论】:

  • 谢谢山姆。对于有问题的问题,我可能会选择以下选项之一:1)避免消费者线程直接发布到环形缓冲区,因为这不是 Disruptor 的主要设计目标,2)将事件发布到单独的线程发布/将事件转发到环形缓冲区,3)编写您提到的那种自定义 EventProcess 并且还需要确保一个传入事件生成不超过一个新事件。 (我会接受这个作为答案)
  • 你明白了。通常设置是网络消费者发布到环形缓冲区 A,业务逻辑消费来自 A 的事件并发布到环形缓冲区 B。环形缓冲区 B 上的消费者会将事件发布回网络。
【解决方案2】:

如果您使用Single producer 设置,那么消费者不能回发到环形缓冲区,因为它不是Single producer

退后一步,为什么只有一个消费者需要写入环形缓冲区?它已经知道它做了什么,没有其他东西会从缓冲区中读取。

如果您有多个消费者,您可以写回缓冲区,但要确保额外的消费者受控于正在写回缓冲区而不是生产者序列的消费者。

【讨论】:

  • 在多消费者设置中,假设当前环形缓冲区已满,消费者线程唤醒以处理第一个事件。处理事件时,需要回写到同一个环形缓冲区。因为正在处理的槽不被视为空闲槽,所以消费者线程将永远无法获得空闲槽,因此会发生死锁。是这样吗?
  • 假设您的消费者也是生产者,即它在环形缓冲区中声明一个新插槽,而不仅仅是在它刚刚读取的插槽处静音,那么是的,您有一个死锁。如果您正在考虑拥有依赖消费者,那么方法是改变您从中读取的插槽中的状态(例如填充反序列化的文件),而不是消耗额外的环形缓冲区插槽。
  • 感谢您的回复,山姆。没有依赖消费者,因为我需要最小化线程数。 (顺便说一句,我在原始问题中添加了一点背景)
猜你喜欢
  • 1970-01-01
  • 2017-04-07
  • 1970-01-01
  • 2019-01-17
  • 1970-01-01
  • 1970-01-01
  • 2019-06-13
  • 1970-01-01
  • 2015-07-03
相关资源
最近更新 更多