我可以从第三个线程监视 boost::lockfree::spsc_queue 吗?

Can I monitor boost::lockfree::spsc_queue from a third thread?

我有一个线程在 boost::lockfree::spsc_queue 上生成数据,还有一个线程使用数据。我可以让第三个线程使用 read_availablewrite_available 监视队列吗?我对准确计数不感兴趣,但我想知道队列是否在稳步增长,因为这意味着消费者跟不上。文档指出 read_available 是:

Thread-safe and wait-free, should only be called from the consumer thread

(https://www.boost.org/doc/libs/1_68_0/doc/html/boost/lockfree/spsc_queue.html)

如果第三个线程尝试调用 read_available 会发生什么?如果它只是得到一个不准确的计数,那很好。如果它可以获得随机数,或者以某种方式破坏事物,那么我想我会使用 std::atomic<int>.

进行计数

您可以让 reader 线程偶尔检查队列大小(比如每 1000 个项目),然后发布 std::atomic<int> qsize(带有 mo_relaxed 存储)第三个线程可以读取。

使用 reader 私有的非原子计数器。 Reader 递减它,并在它达到零时将其重置为 1000 + 发布。将它保存在作者不接触的缓存行中,因此根本没有额外的争用,除了每第 1000 个项目你做一个需要 RFO 才能将值提交到缓存行的存储。但它是只写存储,而不是 RMW,因此存储缓冲区有望隐藏延迟。 (除了在 x86 上,下一个原子 RMW 总是一个完整的障碍,所以它必须等待那个存储提交。但它只是每 1000 个出队操作,所以它几乎不会再减慢 reader 的速度。)

std::atomic<int> reader 和编写器原子 inc/dec 将使它们比 SPSC 队列更容易相互竞争。不像争夺锁那么糟糕,但我预计它会比我建议的更糟糕。


发生的细节可能取决于编译器为目标机器生成的 asm,以及它可以执行何种运行时重新排序。我不知道,但如果文档说它不受支持,如果你想冒险就必须调查或试验。

可能出于某种原因,当 reader 正在使元素出队时调用 read_available() 是不安全的。

您必须查看实现,看看这是否意味着可能会减少一个或全部垃圾。