我有一个问题,如果在 x86 Linux 上运行多个生产者和单个消费者的 lmax 破坏者(如环形缓冲区)中的消费者缓慢,该怎么办。使用类似环形缓冲区的 lmax 模式,您会不断地覆盖数据,但如果消费者速度很慢怎么办。因此,您如何处理在 10 大小的环形缓冲区 0-9 环形槽中,您的消费者位于槽 5 并且现在您的编写者已准备好开始写入槽 15,这也是缓冲区中的槽 5(即:槽5 = 15 % 10)? 处理此问题的典型方法是什么,使得编写者仍然按传入的顺序生成数据,而客户端将以相同的顺序接收数据?这真的是我的问题。下面是关于我的设计的一些细节,它工作正常,只是我目前没有一个好的方法来处理这个问题。
设计细节
我有一个环形缓冲区,设计目前有多个生产者线程和一个消费者线程。这部分设计是存在的,目前无法更改。我正在尝试使用无锁环形缓冲区删除现有的排队系统。我所拥有的如下。
代码在 x86 Linux 上运行,编写器运行多个线程,读取器运行单个线程。读取器和写入器从一个插槽开始,并且是,因此读取器从插槽 0 开始,写入器从插槽 1 开始,然后每个写入器首先通过调用如下所示的方法对写入器序列执行原子操作,然后使用 compare_and_swap 循环std::atomic<uint64_t>
来声明一个插槽要更新阅读器序列以让客户端知道此插槽可用,请参阅.fetch_add(1, std::memory_order::memory_order_acq_rel)
incrementSequence
updateSequence
inline data_type incrementSequence() {
return m_sequence.fetch_add(1,std::memory_order::memory_order_seq_cst);
}
void updateSequence(data_type aOld, data_type aNew) {
while ( !m_sequence.compare_exchange_weak(aOld, aNew, std::memory_order::memory_order_release, std::memory_order_relaxed)
if (sequence() < aNew) {
continue;
}
break;
}
}
inline data_type sequence() const {
return m_sequence.load(std::memory_order::memory_order_acquire);
}