template <class T>
class CircularBuffer:public boost::noncopyable {
public:
CircularBuffer() {}
explicit CircularBuffer(size_t s) {
data_.resize(s);
capacity_ = s;
}
bool closed() const {
return closed_;
}
void open() {
LockGuard lock(mutex_);
if (closed_) {
closed_ = false;
}
}
void close() {
LockGuard lock(mutex_);
closed_ = true;
}
void set_capacity(size_t s) {
LockGuard lock(mutex_);
data_.resize(s);
capacity_ = s;
}
bool empty() const {
LockGuard lock(mutex_);
return capacity_ == data_.size();
}
bool full() const {
LockGuard lock(mutex_);
return capacity_ == 0;
}
bool put(const T&& val) {
UniqueLock lock(mutex_);
write_cond_var_.wait(lock, [this]{
bool writable = this->capacity_ != 0;
if (!writable) {
read_cond_var_.notify_one();
}
return writable;
});
head_ = (head_ + 1) % data_.size();
data_[head_] = val;//Move
capacity_--;
lock.unlock();
read_cond_var_.notify_one();
return true;
}
bool read(std::vector<T*>& p) {
UniqueLock lock(mutex_);
read_cond_var_.wait(lock, [&]{
bool readable = p.size() + this->capacity_ <= this->data_.size();
if (!readable) {
write_cond_var_.notify_all();
}
return readable;
});
int tail = (head_ + capacity_ + 1) % data_.size();
for (int i = 0; i < p.size(); i++) {
int j = (tail + i) % data_.size();
p[i] = &data_[j];
}
return true;
}
void free_capacity(int n) {
LockGuard lock(mutex_);
capacity_ += n;
CHECK(capacity_ <= data_.size());
write_cond_var_.notify_all();
}
private:
typedef std::unique_lock<std::mutex> UniqueLock;
typedef std::lock_guard<std::mutex> LockGuard;
std::condition_variable read_cond_var_;
std::condition_variable write_cond_var_;
bool closed_ = false;
mutable std::mutex mutex_;
std::vector<T> data_;
int head_ = -1;
int capacity_ = 0;
};
基于std vector的ring buffer的实现。
最新推荐文章于 2023-10-26 14:46:24 发布