4

我正在用 C++ 进行多线程编程,我想知道 C++ 中是否有线程安全的 ringbuffer 实现,或者你知道如何实现它。

4

1 回答 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 回答