потокобезопасность — c ++ потокобезопасная реализация кольцевого буфера

Я занимаюсь многопоточным программированием на C ++, и мне интересно, есть ли поточно-ориентированная реализация ringbuffer в C ++ или у вас есть идея, как я могу это реализовать.

4

Решение

Вот базовая реализация. Требует, чтобы объекты, хранящиеся в буфере, были конструируемыми по умолчанию и копируемыми (сохраняя их в std :: vector<>). требует C++11 Поддержка для std::atomic). Большинство любых последних версий gcc будет это с -std=c++11 или же -std=c++0x

Если c++11 недоступен, замените соответствующий встроенный компилятор для создания head_ а также tail_ атомное.

Должен быть безопасным для одного потока чтения и одного потока записи.

Публикуйте статьи по телефону:

  auto val = ringbuffer.back();
val = some_value;
ringbuffer.push();

Получить предметы по телефону:

  auto val = ringbuffer.front();
// do stuff with val
ringbuffer.pop();

Если back() возвращает nullptrто буфер заполнен. Если front() возвращает nullptr тогда буфер «пуст».

Предупреждение, не проверено (вообще): 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_;
};
-1

Другие решения

Других решений пока нет …