我有一个线程将数据生成到boost::lockfree::spsc_queue
上,还有一个线程消耗数据。我可以让第三个线程使用read_available
或write_available
监视队列吗?我对准确的计数不感兴趣,但是我想知道队列是否在稳定增长,因为这意味着消费者没有跟上进度。文档指出read_available
是:
线程安全且无需等待,只能从使用者线程中调用
(https://www.boost.org/doc/libs/1_68_0/doc/html/boost/lockfree/spsc_queue.html)
如果第三个线程尝试调用read_available
会发生什么?如果只是计数不正确,那很好。如果它可以获取随机数或以某种方式破坏事物,那么我想我将使用std::atomic<int>
进行计数。
答案 0 :(得分:1)
您可以让读取器线程偶尔检查队列大小(例如每1000个项目),并发布第三个线程的std::atomic<int> qsize
(带有mo_relaxed
存储)可以阅读。
使用读者专有的非原子计数器。读者将其递减,并在零时将其重置为1000 +发布。将其保存在编写器不会碰到的缓存行中,因此根本没有多余的争用,除非您存储的第1000项商品需要RFO才能将值提交到缓存行。但这是一个只写存储,而不是RMW,因此存储缓冲区有望掩盖延迟。 (在x86上,下一个原子RMW始终是一个完整的障碍,因此它必须等待该存储区提交。但是,它仅执行每1000次出队操作,因此几乎不会使读取器速度变慢。)
拥有std::atomic<int>
的读者和作家原子上的inc / dec会使他们彼此之间的竞争比SPSC队列更多。不像争夺锁那么糟糕,但是我希望它会比我建议的要糟糕得多。
发生的详细信息可能取决于目标计算机的编译器生成的asm,以及它可以执行哪种运行时重新排序。我不知道,但是如果文档说它不受支持,那么如果您要冒险,就必须进行调查或试验。
假定读者在出于某种原因而使元素出队的过程中调用read_available()
是不安全的。
您必须查看实现,看看这是否意味着潜在的一次或全部垃圾破坏。