LockFree MultiConsumer / MultiProducer队列

时间:2015-09-30 05:55:03

标签: queue lock-free

我编写了一个简单的无锁单用户/生产者队列。 它应该像这样工作:

  • 许多消费者可随时阅读
  • 任何时候多个生产者都可以写信给它,添加元素会 稍后提供
  • 写完修改完成后,我们调用" makePushedElementsAvailable()",以便消费者可以阅读新添加的元素

template<typename T, int Size>
class MCMPQueue
{
public:
    MCMPQueue();
    bool tryPushLater(const T &element);
    bool tryPop(T &element);
    void makePushedElementsAvailable();
protected:
private:
    T elements[Size];
    std::atomic<int> iHead, iTail, iWrite;
};

template<typename T, int Size>
MCMPQueue<T, Size>::SCMPQueue() : iHead(0), iTail(0), iWrite(0)
{
}

template<typename T, int Size>
void MCMPQueue<T, Size>::makePushedElementsAvailable()
{
    iTail.store(iWrite.load());
}

template<typename T, int Size>
bool MCMPQueue<T, Size>::tryPop(T &element)
{
    int newIndex;
    int index;
    do {
        index = iHead.load();
        if (index == iTail.load())
            return false;
        newIndex = index + 1;
    } while (!iHead.compare_exchange_weak(index, newIndex));

    index = index % Size;
    element = elements[index];
    return true;
}

template<typename T, int Size>
bool MCMPQueue<T, Size>::tryPushLater(const T &element)
{
    int newIndex;
    int index;
    do {
        index = iWrite.load();
        if (index - iHead.load() >= Size)
            return false;
        newIndex = index + 1;
    } while (!iWrite.compare_exchange_weak(index, newIndex));

    index = index % Size;
    elements[index] = element;
    return true;
}

到目前为止,这似乎工作得很好,我想请其他人检查一下。所有更新完成后,是否有一种比使元素可用更简单的方法?

感谢。

0 个答案:

没有答案