当我阅读有关示例无等待环形缓冲区实现的 boost atomics 时:
我想知道 memory_order_acquire 是否需要
if (next_head == tail_.load(boost::memory_order_acquire))
似乎 memory_order_relaxed 也应该起作用。我的论点是
value = ring_[tail];
发生之前
tail_.store(next(tail), boost::memory_order_release)
在 pop() 调用中。所以我们确定在我们存储 push() 调用之前已经读取了数据
ring_[head] = value;
我在下面粘贴了整个 boost 示例代码以便于参考。谢谢!
#include <boost/atomic.hpp>
template<typename T, size_t Size>
class ringbuffer {
public:
ringbuffer() : head_(0), tail_(0) {}
bool push(const T & value)
{
size_t head = head_.load(boost::memory_order_relaxed);
size_t next_head = next(head);
if (next_head == tail_.load(boost::memory_order_acquire))
//上面的tail_.load可以使用boost::memory_order_relaxed吗?
return false;
ring_[head] = value;
head_.store(next_head, boost::memory_order_release);
return true;
}
bool pop(T & value)
{
size_t tail = tail_.load(boost::memory_order_relaxed);
if (tail == head_.load(boost::memory_order_acquire))
return false;
value = ring_[tail];
tail_.store(next(tail), boost::memory_order_release);
return true;
}
private:
size_t next(size_t current)
{
return (current + 1) % Size;
}
T ring_[Size];
boost::atomic<size_t> head_, tail_;
};