我有这样的队列:
boost::lockfree::spsc_queue<orders_log, boost::lockfree::capacity<8192>> futOrdersUpdates;
我的问题是,有时我会多次将同一项目deque。我添加了一些疑难解答代码:
while (bool dequeued = futOrdersUpdates.pop(entryItem) || !endOfTransaction)
{
if (!dequeued) {
dequeueLoger.Debug("no items, try again");
continue;
} else {
if (lastRev != 0 && entryItem.replRev == lastRev) {
dequeueLoger.Debug("duplicate item!");
}
lastRev = entryItem.replRev;
}
// further processing
这个想法是 - 如果没有设置endOfTransaction
标志,我应该“旋转”,否则我可以在队列为空时退出。
在日志中我发现了一些奇怪的东西:
预期行为:
endOfTransaction
标志时问题是 - 如果我正确地“解压缩”spsc_queue?我的代码中有任何错误吗?
答案 0 :(得分:0)
我们无法知道你为什么要重复,因为我们不知道你如何填补replRev
。这可能是一场数据竞赛(我希望你不要做lastRev+1
,例如)。
请注意,您可能永远不会得到&#34;没有项目会再次尝试&#34;因为循环被完全跳过,例如:
while (bool dequeued = foo())
{
assert(dequeued); // can never be false here!
}
永远不会进入循环。
你得到重复的原因是因为你说
bool dequeued = futOrdersUpdates.pop(entryItem) || !endOfTransaction;
如您所知(请参阅您的评论),即使没有项 出列,强制 dequeued
仍为true
,因为{{1尚未设置。
此时endOfTransaction
的值未指定 - 但可能只包含之前的值,导致&#34;重复&#34;消息。
对于我最近给出的entryItem
的精彩演示,请参阅此答案:Dynamic generation & safe usage of spsc_queues