请使用C加加实现SPSC
时间: 2024-02-27 11:58:49 浏览: 173
SPSC (Single Producer Single Consumer) 是指只有一个生产者和一个消费者的队列。在多线程编程中,SPSC 队列常用于线程之间的通信。
以下是使用 C++ 实现 SPSC 队列的示例代码:
```c++
#include <atomic>
#include <iostream>
template<typename T>
class SPSCQueue {
public:
explicit SPSCQueue(size_t capacity) : capacity_(capacity), size_(0), head_(0), tail_(0) {
buffer_ = new T[capacity_];
}
~SPSCQueue() {
delete[] buffer_;
}
bool enqueue(const T& item) {
size_t current_tail = tail_.load(std::memory_order_relaxed);
size_t next_tail = (current_tail + 1) % capacity_;
if (next_tail == head_.load(std::memory_order_acquire)) {
return false; // queue is full
}
buffer_[current_tail] = item;
tail_.store(next_tail, std::memory_order_release);
size_.fetch_add(1, std::memory_order_relaxed);
return true;
}
bool dequeue(T& item) {
size_t current_head = head_.load(std::memory_order_relaxed);
if (current_head == tail_.load(std::memory_order_acquire)) {
return false; // queue is empty
}
item = buffer_[current_head];
head_.store((current_head + 1) % capacity_, std::memory_order_release);
size_.fetch_sub(1, std::memory_order_relaxed);
return true;
}
size_t size() const {
return size_.load(std::memory_order_relaxed);
}
bool empty() const {
return size() == 0;
}
bool full() const {
return size() == capacity_;
}
private:
size_t capacity_;
T* buffer_;
std::atomic<size_t> size_;
std::atomic<size_t> head_;
std::atomic<size_t> tail_;
};
```
在这个实现中,我们使用了 C++11 中的原子操作来实现线程安全。enqueue() 和 dequeue() 操作都分为三个步骤:
1. 读取队列的头或尾指针
2. 计算下一个头或尾指针
3. 更新头或尾指针
在读取头或尾指针时,我们使用 std::memory_order_relaxed 参数来告诉编译器不需要进行同步和排序。这是因为我们只需要保证在更新头或尾指针之前,头或尾指针的值是正确的。在更新头或尾指针时,我们使用 std::memory_order_acquire 或 std::memory_order_release 参数来分别保证读取和写入的同步和排序。这是因为我们需要保证在更新头或尾指针之后,其他线程能够正确读取头或尾指针的值。
此外,我们还使用了一个 size_ 变量来记录队列中的元素个数。这个变量也需要使用原子操作来保证线程安全。
最后,我们还提供了一些辅助函数来查询队列的状态,如 size()、empty() 和 full()。
阅读全文