boost::lockfree::spsc_queue的read_available和write_available应该如何使用?

How should boost::lockfree::spsc_queue's read_available and write_available be used?

Boost documentation for spsc_queue 说:

read_available():线程安全且无等待,只应从生产者线程调用

write_available():线程安全且无等待,只应从消费者线程调用

我希望最常见的用例正好相反:生产者线程(线程 向队列写入 数据)需要 write_available(),并且消费者线程(线程 从队列中读取 数据)需要 read_available().

如果我需要知道我可以在生产者线程中写入多少队列,我应该使用QUEUE_CAPACITY - read_available()吗?

任何类型的大小评估都将成为无锁世界中的一场竞赛。

原因很简单,在您对 "measured size" 采取行动之前,其他线程上的大小可能会发生变化。

Single-Producer/Single-Consumer 是 特殊的 ,因为消费者 知道 没有其他人可以从队列中读取(所以 "read_available" 永远不会减少 除非消费者自己阅读 )。生产方也是如此。

很明显write_available就是你需要的。当然,到您实际写作时可能 更多,但您无法获得更准确的信息。至少永远不会less(毕竟生产者线程只有1个)

Note that the documentation appears to be in error (swapping the allowed threads)

This made me double check, and sure enough they use the functions internally in the expected ways (contradicting the erronous documentation claim):

ConstIterator push(ConstIterator begin, ConstIterator end, T * internal_buffer, size_t max_size)
{
    const size_t write_index = write_index_.load(memory_order_relaxed);  // only written from push thread
    const size_t read_index  = read_index_.load(memory_order_acquire);
    const size_t avail = write_available(write_index, read_index, max_size);

我衷心建议使用此处显示的范围推送来自动推送可能的确切项目数。例如:

auto b = messages.begin(), e = messages.end();
do {
    b = a.push(b, e)
} while (b != e);