1

我正在尝试编写线程安全有界的两侧堆栈的实现而不会阻塞。
push操作中,我需要比较sizecapacity如果它们不相等,则为堆栈设置新的头元素。
真正的方法是什么?
如果我写

if (size == cap) {
   return;
}

// append element

我不确定其他线程不会在比较后立即将最后一个值推入堆栈。

#include <atomic>
#include <boost/next_prior.hpp>
#include <boost/lockfree/spsc_queue.hpp>
#include <boost/function.hpp>

template<typename T>
struct Node
{
    Node(const T& data)
        :data(data), next(nullptr) {}

public:
    T data;

    Node* next;
};

template <typename T>
class Stack {
    using WriteCallback = typename std::function<void (const T&)>;
    using ReadCallback  = typename std::function<void (T&&)>;

    template<typename T1>
    using queue = boost::lockfree::spsc_queue<T1>;

public:
    Stack(int cap)
        :head(nullptr),
         size(0),
         cap(cap),
         onWrite(0),
         onRead(0)
    {}

    void push(const T& val, WriteCallback cb)
    {
        if (size == cap) {
            onWrite.push(cb);
            return;
        }
        // insertion will be here
    }

private:
    Node* head;

    std::atomic<int> size;
    std::atomic<int> cap;

    queue<WriteCallback> onWrite;
    queue<ReadCallback>  onRead;
};
4

1 回答 1

0

您在寻找原子比较和交换吗?

您可以使用atomic_compare_exchangeC11 中的任何一个,如果它可用于您的编译器,或者寻找系统相关和编译器相关的lock cmpxchg内在函数。

例如,对于 msvc:https ://msdn.microsoft.com/en-us/library/ttk2z1ws.aspx

编辑:刚刚在 C++ 11 中找到了这个:std::atomic::compare_exchange_weak/ std::atomic::compare_exchange_strong

于 2018-11-12T12:01:47.553 回答