Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
cmake_minimum_required(VERSION 3.20)
project(chapter07_03_circular_buffer CXX)
project(chapter08_08_circular_buffer CXX)

set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,69 +1,68 @@
// atomic_ring_buffer.h - 线程安全的循环缓冲区实现
#pragma once
#include <cstddef>
#include <array>
#include <atomic>

template<typename T, std::size_t Capacity>
class AtomicRingBuffer {
public:
AtomicRingBuffer() : head_(0), tail_(0) {}

bool push(const T& value) {
std::size_t head = head_.load(std::memory_order_relaxed);
std::size_t next_head = (head + 1) % Capacity;
std::size_t tail = tail_.load(std::memory_order_acquire);

if (next_head == tail) {
return false; // 缓冲区满了
}

buffer_[head] = value;
head_.store(next_head, std::memory_order_release);
return true;
}

bool pop(T& out) {
std::size_t tail = tail_.load(std::memory_order_relaxed);
std::size_t head = head_.load(std::memory_order_acquire);

if (tail == head) {
return false; // 没数据
}

out = buffer_[tail];
std::size_t next_tail = (tail + 1) % Capacity;
tail_.store(next_tail, std::memory_order_release);
return true;
}

bool empty() const {
std::size_t head = head_.load(std::memory_order_acquire);
std::size_t tail = tail_.load(std::memory_order_acquire);
return head == tail;
}

bool full() const {
std::size_t head = head_.load(std::memory_order_acquire);
std::size_t tail = tail_.load(std::memory_order_acquire);
return (head + 1) % Capacity == tail;
}

std::size_t size() const {
std::size_t head = head_.load(std::memory_order_acquire);
std::size_t tail = tail_.load(std::memory_order_acquire);
if (head >= tail) {
return head - tail;
}
return Capacity - (tail - head);
}

std::size_t capacity() const {
return Capacity - 1; // 实际可用容量
}

private:
std::array<T, Capacity> buffer_;
std::atomic<std::size_t> head_;
std::atomic<std::size_t> tail_;
};
// atomic_ring_buffer.h - 线程安全的循环缓冲区实现
#pragma once
#include <array>
#include <atomic>
#include <cstddef>

template <typename T, std::size_t Capacity> class AtomicRingBuffer {
public:
AtomicRingBuffer() : head_(0), tail_(0) {}

bool push(const T& value) {
std::size_t head = head_.load(std::memory_order_relaxed);
std::size_t next_head = (head + 1) % Capacity;
std::size_t tail = tail_.load(std::memory_order_acquire);

if (next_head == tail) {
return false; // 缓冲区满了
}

buffer_[head] = value;
head_.store(next_head, std::memory_order_release);
return true;
}

bool pop(T& out) {
std::size_t tail = tail_.load(std::memory_order_relaxed);
std::size_t head = head_.load(std::memory_order_acquire);

if (tail == head) {
return false; // 没数据
}

out = buffer_[tail];
std::size_t next_tail = (tail + 1) % Capacity;
tail_.store(next_tail, std::memory_order_release);
return true;
}

bool empty() const {
std::size_t head = head_.load(std::memory_order_acquire);
std::size_t tail = tail_.load(std::memory_order_acquire);
return head == tail;
}

bool full() const {
std::size_t head = head_.load(std::memory_order_acquire);
std::size_t tail = tail_.load(std::memory_order_acquire);
return (head + 1) % Capacity == tail;
}

std::size_t size() const {
std::size_t head = head_.load(std::memory_order_acquire);
std::size_t tail = tail_.load(std::memory_order_acquire);
if (head >= tail) {
return head - tail;
}
return Capacity - (tail - head);
}

std::size_t capacity() const {
return Capacity - 1; // 实际可用容量
}

private:
std::array<T, Capacity> buffer_;
std::atomic<std::size_t> head_;
std::atomic<std::size_t> tail_;
};
Original file line number Diff line number Diff line change
@@ -1,50 +1,50 @@
// basic_example.cpp - 循环缓冲区基本用法演示
#include "ring_buffer.h"
#include <iostream>
int main() {
// 创建一个容量为 16 的循环缓冲区(实际可用 15)
RingBuffer<int, 16> buffer;
std::cout << "Ring Buffer Demo\n";
std::cout << "Capacity: " << buffer.capacity() << "\n\n";
// 测试:填充和读取
std::cout << "=== Pushing 10 elements ===\n";
for (int i = 0; i < 10; ++i) {
if (buffer.push(i)) {
std::cout << "Pushed: " << i << ", size: " << buffer.size() << '\n';
}
}
std::cout << "\n=== Popping 5 elements ===\n";
for (int i = 0; i < 5; ++i) {
int value;
if (buffer.pop(value)) {
std::cout << "Popped: " << value << ", size: " << buffer.size() << '\n';
}
}
std::cout << "\n=== Pushing 8 more elements ===\n";
for (int i = 10; i < 18; ++i) {
if (buffer.push(i)) {
std::cout << "Pushed: " << i << ", size: " << buffer.size() << '\n';
} else {
std::cout << "Failed to push: " << i << " (buffer full)\n";
}
}
std::cout << "\n=== Remaining contents ===\n";
while (!buffer.empty()) {
int value;
buffer.pop(value);
std::cout << value << ' ';
}
std::cout << "\n";
std::cout << "\nFinal size: " << buffer.size() << '\n';
std::cout << "Empty: " << (buffer.empty() ? "yes" : "no") << '\n';
std::cout << "Full: " << (buffer.full() ? "yes" : "no") << '\n';
return 0;
}
// basic_example.cpp - 循环缓冲区基本用法演示
#include "ring_buffer.h"
#include <iostream>

int main() {
// 创建一个容量为 16 的循环缓冲区(实际可用 15)
RingBuffer<int, 16> buffer;

std::cout << "Ring Buffer Demo\n";
std::cout << "Capacity: " << buffer.capacity() << "\n\n";

// 测试:填充和读取
std::cout << "=== Pushing 10 elements ===\n";
for (int i = 0; i < 10; ++i) {
if (buffer.push(i)) {
std::cout << "Pushed: " << i << ", size: " << buffer.size() << '\n';
}
}

std::cout << "\n=== Popping 5 elements ===\n";
for (int i = 0; i < 5; ++i) {
int value;
if (buffer.pop(value)) {
std::cout << "Popped: " << value << ", size: " << buffer.size() << '\n';
}
}

std::cout << "\n=== Pushing 8 more elements ===\n";
for (int i = 10; i < 18; ++i) {
if (buffer.push(i)) {
std::cout << "Pushed: " << i << ", size: " << buffer.size() << '\n';
} else {
std::cout << "Failed to push: " << i << " (buffer full)\n";
}
}

std::cout << "\n=== Remaining contents ===\n";
while (!buffer.empty()) {
int value;
buffer.pop(value);
std::cout << value << ' ';
}
std::cout << "\n";

std::cout << "\nFinal size: " << buffer.size() << '\n';
std::cout << "Empty: " << (buffer.empty() ? "yes" : "no") << '\n';
std::cout << "Full: " << (buffer.full() ? "yes" : "no") << '\n';

return 0;
}
Original file line number Diff line number Diff line change
@@ -1,56 +1,49 @@
// ring_buffer.h - 简单的循环缓冲区实现
#pragma once
#include <cstddef>
#include <array>

template<typename T, std::size_t Capacity>
class RingBuffer {
public:
bool push(const T& value) {
if (full()) {
return false; // 缓冲区满了
}

buffer_[head_] = value;
head_ = (head_ + 1) % Capacity;
return true;
}

bool pop(T& out) {
if (empty()) {
return false; // 没数据
}

out = buffer_[tail_];
tail_ = (tail_ + 1) % Capacity;
return true;
}

bool empty() const {
return head_ == tail_;
}

bool full() const {
return (head_ + 1) % Capacity == tail_;
}

std::size_t size() const {
if (head_ >= tail_) {
return head_ - tail_;
}
return Capacity - (tail_ - head_);
}

std::size_t capacity() const {
return Capacity - 1; // 实际可用容量
}

void clear() {
head_ = tail_ = 0;
}

private:
std::array<T, Capacity> buffer_{};
std::size_t head_ = 0;
std::size_t tail_ = 0;
};
// ring_buffer.h - 简单的循环缓冲区实现
#pragma once
#include <array>
#include <cstddef>

template <typename T, std::size_t Capacity> class RingBuffer {
public:
bool push(const T& value) {
if (full()) {
return false; // 缓冲区满了
}

buffer_[head_] = value;
head_ = (head_ + 1) % Capacity;
return true;
}

bool pop(T& out) {
if (empty()) {
return false; // 没数据
}

out = buffer_[tail_];
tail_ = (tail_ + 1) % Capacity;
return true;
}

bool empty() const { return head_ == tail_; }

bool full() const { return (head_ + 1) % Capacity == tail_; }

std::size_t size() const {
if (head_ >= tail_) {
return head_ - tail_;
}
return Capacity - (tail_ - head_);
}

std::size_t capacity() const {
return Capacity - 1; // 实际可用容量
}

void clear() { head_ = tail_ = 0; }

private:
std::array<T, Capacity> buffer_{};
std::size_t head_ = 0;
std::size_t tail_ = 0;
};
Loading
Loading