Boost的无锁队列有可能丢元素吗?

Is it possible for Boost's lockfree queue to lose elements?

我有一个单线程应用程序,它使用boost::lockfree::queue(来自Boost 1.57)。 (我使用队列的原因是它是多线程应用程序中也使用的库的一部分。)

队列似乎以某种方式丢失了元素。

使用队列的class表现如下:

我观察到元素似乎没有在系统中持续传播,因此使用 std::atomic_uints,我创建了一些计数器来检查离开队列的警报数量是否与进入队列的警报数量相同:

在循环之后,我检查计数器和队列的状态并进行健全性检查:

auto postconsume_pushed_method1 = pushed_method1.load();
auto postconsume_pushed_method2 = pushed_method2.load();
auto all_consumed = my_queue.empty();

assert(
    !all_consumed
  ||  postconsume_pushed_method1 + postconsume_pushed_method2
        == consumed + skipped);

这个断言通常 通过——但在我的单线程应用中它有时会失败 ]. (它有时在多线程情况下也会失败,但我希望关注单线程情况以简化问题。)

在多线程的情况下,我可以想象操作被重新排序,以便在 .empty() 检查之后出现一个或多个 loads,但我希望这是不是这种情况,因为我希望 std::atomicboost::lockfree 包含用于此类事情的内存栅栏。

然而,在单线程的情况下,这个应该无关紧要,因为元素应该永远不会push在应用程序执行 "consume" 方法时编辑,并且警报队列应该 始终 在循环之后为空(因为循环不会中断,直到 pop returns false).

我是不是误会了什么?我的逻辑有错误吗?我在 boost::lockfree::queue 中发现错误的可能性很小吗?

队列是无锁的,因此push队列满时不会阻塞。

lockfree::queue::push returns 一个布尔值,表示元素是否已进入队列。当队列已满时 push returns false,因此您可能想检查一下这种情况。