我已经在无锁队列上的单个生产者/消费者上完成了我的基本实现,并且运行良好。但是,当我尝试将其扩展到多个生产者/消费者时,我开始遇到冲突。我通过SO找到了与此问题相关的类似帖子(Is there such a thing as a lockless queue for multiple read or write threads?),我发现了一篇文章,对原始实现进行了进一步的介绍。我也对这篇希望得到一些指导的文章感到困惑。
第一个是这个实现在使用多个生产者/消费者时真的有用吗?或者在原始的Michael-Scott实现中缺少某些与多个生产者/消费者设置一起工作的东西。
第二个是文章An Optimistic Approach to Lock-Free FIFO Queues,Dequeue部分显示了虚拟值的使用。如何确定要使用的适当值?如果我使用整数,那么我会确定我为虚拟值选择的整数不是我决定排队的实际值吗?
任何建议或总体方向都会很棒。如果有人想知道我在Visual Studio中创建它以更好地理解非阻塞算法。我想尽可能地使它成为通用的,这样我就可以排队所需的任何内容(队列中的数据是模板化的,因此用户可以指定要排队的内容)。
答案 0 :(得分:5)
谨防邪恶:ABA problem。
答案 1 :(得分:0)
您可以制作便宜的包装类型,以便您可以跟踪项目的有效性,并且用户可以透明地传递值而不必担心它。这会产生一些小的内存开销,但是如果你想允许空值的入队和出列(而不是将它们视为“虚拟”标记),那么实际上并没有更好的方法。
示例:
template<typename T>
class MyQueue
{
/* . . . */
public:
void Enqueue(T * value)
{
MyQueueItem item;
item.value = value;
item.isValid = true;
/* enqueue it now
. . . */
}
T * Dequeue()
{
MyQueueItem validItem;
/* Get the first element where isValid == true
. . . */
return validItem.value;
}
private:
struct MyQueueItem
{
T * value;
bool isValid;
};
};
答案 2 :(得分:0)
没有明确支持在C ++中实现非阻塞队列所需的原子cpu指令(但是,它在更新的规范中)。
可以访问您机器上的说明,但您必须内联某个程序集或找到为您执行此操作的库(TBB或升级版)。