用于无等待生产者和阻塞消费者的环形缓冲区
Ring buffer for a wait-free producer and a blocking consumer
我有一个生产者线程,其生产对象的速度可能(暂时)快到消费者线程无法消费。因此,我想要一个 FIFO 来缓冲剩余的工作。一旦 FIFO 已满,生产者只需退出或稍后重试。此外,我希望能够通知消费者没有更多工作要做(无需将特殊对象排队到 FIFO 中)。生产者不得减速,消费者不得浪费CPU周期,所以我有以下要求:
- 固定大小的环形缓冲区。
- 生产者永远不会等待:它需要能够尽快将元素排入队列。
- 消费者应该能够阻止:没有忙等待可能很慢的生产者。混合锁会很好。
我正在设想以下 C++ class:
template <typename T, std::size_t N>
class spsc_circular_half_blocking {
std::array<T, N> buffer;
// bookkeeping, atomics, mutexes etc. go here
public:
bool try_push(const T&); // returns whether object could be enqueued
void notify(); // notifies consumer
bool wait_pop(T&); // returns whether object was dequeued or notification was received
};
能够就地修改元素会很好。它还可以使用缓冲区的动态分配(例如,大小传递给构造函数,缓冲区是 unique_ptr
)。
现在回答我的问题。这件事甚至可能吗(至少在 x86 上)?
- 如果是,它是如何工作的?我真的很想要一些实现,最好但不一定是 C++。
- 如果没有,为什么不呢?
相关 material 的指针,即使它不能完全满足我的需求,也将不胜感激。
一种解决方案是将 boost single-producer single-consumer queue 与您自己的信令和阻塞一起使用。
Google 找到了这个,对此一无所知,但也许值得研究一下:
无等待多生产者多消费者环形缓冲区:
我有一个生产者线程,其生产对象的速度可能(暂时)快到消费者线程无法消费。因此,我想要一个 FIFO 来缓冲剩余的工作。一旦 FIFO 已满,生产者只需退出或稍后重试。此外,我希望能够通知消费者没有更多工作要做(无需将特殊对象排队到 FIFO 中)。生产者不得减速,消费者不得浪费CPU周期,所以我有以下要求:
- 固定大小的环形缓冲区。
- 生产者永远不会等待:它需要能够尽快将元素排入队列。
- 消费者应该能够阻止:没有忙等待可能很慢的生产者。混合锁会很好。
我正在设想以下 C++ class:
template <typename T, std::size_t N>
class spsc_circular_half_blocking {
std::array<T, N> buffer;
// bookkeeping, atomics, mutexes etc. go here
public:
bool try_push(const T&); // returns whether object could be enqueued
void notify(); // notifies consumer
bool wait_pop(T&); // returns whether object was dequeued or notification was received
};
能够就地修改元素会很好。它还可以使用缓冲区的动态分配(例如,大小传递给构造函数,缓冲区是 unique_ptr
)。
现在回答我的问题。这件事甚至可能吗(至少在 x86 上)?
- 如果是,它是如何工作的?我真的很想要一些实现,最好但不一定是 C++。
- 如果没有,为什么不呢?
相关 material 的指针,即使它不能完全满足我的需求,也将不胜感激。
一种解决方案是将 boost single-producer single-consumer queue 与您自己的信令和阻塞一起使用。
Google 找到了这个,对此一无所知,但也许值得研究一下:
无等待多生产者多消费者环形缓冲区: