我正在用 C++ 进行多线程编程,我想知道 C++ 中是否有线程安全的 ringbuffer 实现,或者你知道如何实现它。
问问题
9920 次
1 回答
-1
这是一个基本的实现。要求存储在缓冲区中的对象是默认可构造和可复制的(通过将它们存储在 std::vector<> 中)。需要C++11
支持(对于std::atomic
)。大多数最新版本都gcc
将带有-std=c++11
或-std=c++0x
如果c++11
不可用,请用适当的编译器内在函数代替 makehead_
和tail_
atomic。
对于一个阅读器线程和一个编写器线程应该是安全的。
通过调用发布项目:
auto val = ringbuffer.back();
val = some_value;
ringbuffer.push();
通过调用检索项目:
auto val = ringbuffer.front();
// do stuff with val
ringbuffer.pop();
如果back()
返回 a nullptr
,则缓冲区是“满的”。如果front()
返回 anullptr
则缓冲区为“空”。
警告,未测试(完全):D
#include <vector>
template <class T>
class RingBuffer
{
public:
RingBuffer(size_t buffer_size)
: ring_(buffer_size)
, buffer_size_(buffer_size)
, head_(0)
, tail_(0)
{
}
T* back()
{
bool received = false;
if(available(head_, tail_))
{
return &(ring_[head_ % buffer_size_]);
}
return nullptr;
}
void push()
{
++head_;
}
T* front()
{
if(tail_ < head_)
{
return & ring_[tail_ % buffer_size_];
}
return nullptr;
}
void pop()
{
++tail_;
}
size_t size() const
{
if(tail_ < head_)
return buffer_size_ - ((tail_ + buffer_size_) - head_);
else if(tail_ > head_)
return buffer_size_ - (tail_ - head_);
return 0;
}
bool available()
{
return available(head_, tail_);
}
private:
bool available(uint64_t h, uint64_t t) const
{
if(h == t)
return true;
else if(t > h)
return (t - h) > buffer_size_;
else// if(h > t)
return (t + buffer_size_) - h > 0;
}
std::vector<T> ring_;
const size_t buffer_size_;
std::atomic<uint64_t> head_;
std::atomic<uint64_t> tail_;
};
于 2013-09-27T20:37:07.120 回答