1. 队列基础概念与核心特性
队列(Queue)是计算机科学中最基础且重要的数据结构之一,它遵循先进先出(FIFO)的原则。想象一下超市收银台前的队伍——先来排队的顾客会先得到服务,后来者只能排在队尾,这就是队列在现实世界中的完美体现。
队列的两个基本操作是入队(enqueue)和出队(dequeue)。入队操作在队尾添加元素,出队操作则从队首移除元素。这种特性使得队列成为处理有序任务的理想选择,比如:
- 打印机任务调度
- 消息传递系统
- 网络数据包缓冲
- 多线程编程中的任务分配
在C++中,队列可以通过多种方式实现。标准模板库(STL)提供了现成的queue容器,但理解其底层实现原理对于开发者来说至关重要。下面是一个最简单的队列接口定义:
cpp复制template <typename T>
class Queue {
public:
virtual void enqueue(const T& item) = 0;
virtual T dequeue() = 0;
virtual bool isEmpty() const = 0;
virtual size_t size() const = 0;
};
2. 队列的C++实现方案对比
2.1 基于数组的静态队列实现
数组实现是最直观的方式,但需要处理"假溢出"问题——即数组未满但因头尾指针位置关系无法继续入队的情况。解决方案是使用循环数组:
cpp复制template <typename T, size_t Capacity>
class ArrayQueue {
private:
T data[Capacity];
size_t front = 0;
size_t rear = 0;
size_t count = 0;
public:
void enqueue(const T& item) {
if (count == Capacity)
throw std::runtime_error("Queue is full");
data[rear] = item;
rear = (rear + 1) % Capacity;
++count;
}
T dequeue() {
if (count == 0)
throw std::runtime_error("Queue is empty");
T item = data[front];
front = (front + 1) % Capacity;
--count;
return item;
}
// 其他接口实现...
};
这种实现的优点是内存连续、访问速度快,但缺点是需要预先确定容量,不适合动态变化的需求场景。
2.2 基于链表的动态队列实现
链表实现解决了固定容量的问题,可以动态增长:
cpp复制template <typename T>
class LinkedListQueue {
private:
struct Node {
T data;
Node* next;
Node(const T& d) : data(d), next(nullptr) {}
};
Node* head = nullptr;
Node* tail = nullptr;
size_t count = 0;
public:
~LinkedListQueue() {
while (head) {
Node* temp = head;
head = head->next;
delete temp;
}
}
void enqueue(const T& item) {
Node* newNode = new Node(item);
if (tail) {
tail->next = newNode;
} else {
head = newNode;
}
tail = newNode;
++count;
}
T dequeue() {
if (!head)
throw std::runtime_error("Queue is empty");
T item = head->data;
Node* temp = head;
head = head->next;
if (!head) tail = nullptr;
delete temp;
--count;
return item;
}
// 其他接口实现...
};
链表实现的优点是动态扩容,但每个元素需要额外的指针空间,且内存不连续可能导致缓存命中率降低。
2.3 STL queue容器深度解析
C++标准库中的queue实际上是一个容器适配器,默认使用deque作为底层容器:
cpp复制#include <queue>
#include <list>
// 默认使用deque
std::queue<int> q1;
// 也可以指定底层容器
std::queue<int, std::list<int>> q2;
STL queue的主要接口包括:
- push() - 入队
- pop() - 出队
- front() - 访问队首元素
- back() - 访问队尾元素
- empty() - 判断是否为空
- size() - 获取元素数量
3. 高级队列变体与实现
3.1 双端队列(Deque)
双端队列允许在两端进行插入和删除操作,结合了队列和栈的特性:
cpp复制template <typename T>
class Deque {
private:
struct Node {
T data;
Node* prev;
Node* next;
Node(const T& d) : data(d), prev(nullptr), next(nullptr) {}
};
Node* head = nullptr;
Node* tail = nullptr;
size_t count = 0;
public:
// 前端操作
void pushFront(const T& item) {
Node* newNode = new Node(item);
if (head) {
newNode->next = head;
head->prev = newNode;
} else {
tail = newNode;
}
head = newNode;
++count;
}
T popFront() {
if (!head)
throw std::runtime_error("Deque is empty");
T item = head->data;
Node* temp = head;
head = head->next;
if (head) head->prev = nullptr;
else tail = nullptr;
delete temp;
--count;
return item;
}
// 后端操作类似...
};
3.2 优先队列(Priority Queue)
优先队列中元素按优先级出队,而非插入顺序。通常使用堆结构实现:
cpp复制#include <vector>
#include <algorithm>
template <typename T, typename Compare = std::less<T>>
class PriorityQueue {
private:
std::vector<T> heap;
Compare comp;
void heapifyUp(size_t index) {
while (index > 0) {
size_t parent = (index - 1) / 2;
if (comp(heap[parent], heap[index])) {
std::swap(heap[parent], heap[index]);
index = parent;
} else {
break;
}
}
}
void heapifyDown(size_t index) {
size_t left, right, largest;
while (true) {
left = 2 * index + 1;
right = 2 * index + 2;
largest = index;
if (left < heap.size() && comp(heap[largest], heap[left]))
largest = left;
if (right < heap.size() && comp(heap[largest], heap[right]))
largest = right;
if (largest != index) {
std::swap(heap[index], heap[largest]);
index = largest;
} else {
break;
}
}
}
public:
void push(const T& item) {
heap.push_back(item);
heapifyUp(heap.size() - 1);
}
T pop() {
if (heap.empty())
throw std::runtime_error("Priority queue is empty");
T item = heap.front();
heap[0] = heap.back();
heap.pop_back();
if (!heap.empty()) {
heapifyDown(0);
}
return item;
}
// 其他接口...
};
4. 队列在实际项目中的应用案例
4.1 多线程任务调度
队列是多线程编程中任务分配的核心数据结构:
cpp复制#include <queue>
#include <thread>
#include <mutex>
#include <condition_variable>
template <typename T>
class ThreadSafeQueue {
private:
std::queue<T> queue;
mutable std::mutex mtx;
std::condition_variable cv;
public:
void push(T item) {
std::lock_guard<std::mutex> lock(mtx);
queue.push(std::move(item));
cv.notify_one();
}
bool tryPop(T& item) {
std::lock_guard<std::mutex> lock(mtx);
if (queue.empty()) return false;
item = std::move(queue.front());
queue.pop();
return true;
}
void waitAndPop(T& item) {
std::unique_lock<std::mutex> lock(mtx);
cv.wait(lock, [this]{ return !queue.empty(); });
item = std::move(queue.front());
queue.pop();
}
// 其他线程安全接口...
};
4.2 消息队列系统实现
消息队列是分布式系统的核心组件,下面是一个简化版实现:
cpp复制#include <unordered_map>
#include <vector>
class MessageQueue {
private:
struct Message {
std::string topic;
std::string content;
int64_t timestamp;
};
std::unordered_map<std::string, std::vector<Message>> topics;
std::mutex mtx;
public:
void publish(const std::string& topic, const std::string& message) {
std::lock_guard<std::mutex> lock(mtx);
Message msg{topic, message, getCurrentTimestamp()};
topics[topic].push_back(msg);
}
bool subscribe(const std::string& topic,
std::function<void(const Message&)> callback) {
std::lock_guard<std::mutex> lock(mtx);
auto it = topics.find(topic);
if (it == topics.end()) return false;
for (const auto& msg : it->second) {
callback(msg);
}
return true;
}
// 其他消息队列功能...
};
4.3 网络数据包处理
网络框架中常用队列缓冲接收到的数据包:
cpp复制class PacketProcessor {
private:
struct Packet {
uint8_t* data;
size_t length;
uint32_t sourceIP;
};
ThreadSafeQueue<Packet> packetQueue;
std::atomic<bool> running{true};
void processPackets() {
while (running) {
Packet pkt;
if (packetQueue.tryPop(pkt)) {
// 处理数据包
handlePacket(pkt);
delete[] pkt.data;
} else {
std::this_thread::yield();
}
}
}
public:
void start() {
std::thread worker(&PacketProcessor::processPackets, this);
worker.detach();
}
void stop() {
running = false;
}
void receivePacket(uint8_t* data, size_t len, uint32_t ip) {
uint8_t* copy = new uint8_t[len];
std::memcpy(copy, data, len);
packetQueue.push(Packet{copy, len, ip});
}
// 其他网络处理逻辑...
};
5. 性能优化与最佳实践
5.1 内存预分配策略
对于性能敏感的场景,预先分配内存可以显著减少动态内存分配的开销:
cpp复制template <typename T, size_t BlockSize = 1024>
class BlockAllocator {
private:
struct Block {
T items[BlockSize];
Block* next;
};
Block* currentBlock = nullptr;
size_t pos = BlockSize;
std::vector<Block*> blocks;
public:
T* allocate() {
if (pos >= BlockSize) {
currentBlock = new Block();
currentBlock->next = nullptr;
blocks.push_back(currentBlock);
pos = 0;
}
return ¤tBlock->items[pos++];
}
~BlockAllocator() {
for (Block* block : blocks) {
delete block;
}
}
};
template <typename T>
class HighPerfQueue {
private:
struct Node {
T data;
Node* next;
};
Node* head = nullptr;
Node* tail = nullptr;
BlockAllocator<Node> allocator;
public:
void enqueue(const T& item) {
Node* newNode = allocator.allocate();
newNode->data = item;
newNode->next = nullptr;
if (tail) {
tail->next = newNode;
} else {
head = newNode;
}
tail = newNode;
}
// 其他队列操作...
};
5.2 无锁队列实现
对于极高并发场景,无锁队列可以消除锁竞争:
cpp复制#include <atomic>
template <typename T>
class LockFreeQueue {
private:
struct Node {
T data;
std::atomic<Node*> next;
Node(const T& d) : data(d), next(nullptr) {}
};
std::atomic<Node*> head;
std::atomic<Node*> tail;
public:
LockFreeQueue() {
Node* dummy = new Node(T());
head.store(dummy);
tail.store(dummy);
}
~LockFreeQueue() {
while (Node* oldHead = head.load()) {
head.store(oldHead->next.load());
delete oldHead;
}
}
void enqueue(const T& item) {
Node* newNode = new Node(item);
Node* oldTail = nullptr;
Node* temp = nullptr;
while (true) {
oldTail = tail.load();
temp = oldTail->next.load();
if (oldTail == tail.load()) {
if (temp == nullptr) {
if (oldTail->next.compare_exchange_weak(temp, newNode)) {
break;
}
} else {
tail.compare_exchange_weak(oldTail, temp);
}
}
}
tail.compare_exchange_weak(oldTail, newNode);
}
bool dequeue(T& result) {
Node* oldHead = nullptr;
Node* next = nullptr;
while (true) {
oldHead = head.load();
Node* oldTail = tail.load();
next = oldHead->next.load();
if (oldHead == head.load()) {
if (oldHead == oldTail) {
if (next == nullptr) return false;
tail.compare_exchange_weak(oldTail, next);
} else {
result = next->data;
if (head.compare_exchange_weak(oldHead, next)) {
break;
}
}
}
}
delete oldHead;
return true;
}
};
5.3 缓存友好设计
优化内存访问模式可以提高缓存命中率:
cpp复制template <typename T, size_t Capacity>
class CacheOptimizedQueue {
private:
struct alignas(64) CacheLine {
T data[Capacity];
std::atomic<size_t> head{0};
std::atomic<size_t> tail{0};
CacheLine* next{nullptr};
};
CacheLine* currentLine = new CacheLine();
std::atomic<CacheLine*> headLine{currentLine};
std::atomic<CacheLine*> tailLine{currentLine};
public:
void enqueue(const T& item) {
size_t tail = currentLine->tail.load();
while (true) {
if (tail < Capacity) {
if (currentLine->tail.compare_exchange_weak(tail, tail + 1)) {
currentLine->data[tail] = item;
return;
}
} else {
CacheLine* newLine = new CacheLine();
newLine->data[0] = item;
newLine->tail.store(1);
CacheLine* oldTail = tailLine.load();
oldTail->next = newLine;
tailLine.store(newLine);
currentLine = newLine;
return;
}
}
}
bool dequeue(T& result) {
CacheLine* line = headLine.load();
while (line) {
size_t head = line->head.load();
if (head < line->tail.load()) {
if (line->head.compare_exchange_weak(head, head + 1)) {
result = line->data[head];
return true;
}
} else {
CacheLine* nextLine = line->next;
if (nextLine == nullptr) return false;
if (headLine.compare_exchange_weak(line, nextLine)) {
delete line;
}
line = headLine.load();
}
}
return false;
}
~CacheOptimizedQueue() {
CacheLine* line = headLine.load();
while (line) {
CacheLine* next = line->next;
delete line;
line = next;
}
}
};
6. 测试与调试技巧
6.1 单元测试策略
完善的单元测试是队列实现的保障:
cpp复制#include <gtest/gtest.h>
TEST(QueueTest, BasicOperations) {
ArrayQueue<int, 10> q;
EXPECT_TRUE(q.isEmpty());
EXPECT_EQ(q.size(), 0);
q.enqueue(1);
q.enqueue(2);
EXPECT_FALSE(q.isEmpty());
EXPECT_EQ(q.size(), 2);
EXPECT_EQ(q.dequeue(), 1);
EXPECT_EQ(q.dequeue(), 2);
EXPECT_TRUE(q.isEmpty());
}
TEST(QueueTest, CircularBehavior) {
ArrayQueue<int, 3> q;
q.enqueue(1);
q.enqueue(2);
q.enqueue(3);
q.dequeue();
q.enqueue(4); // 应该能成功,因为队列不是真的满
EXPECT_EQ(q.dequeue(), 2);
EXPECT_EQ(q.dequeue(), 3);
EXPECT_EQ(q.dequeue(), 4);
}
TEST(QueueTest, ThreadSafety) {
ThreadSafeQueue<int> q;
const int NUM_THREADS = 4;
const int OPS_PER_THREAD = 1000;
std::vector<std::thread> producers;
std::vector<std::thread> consumers;
std::atomic<int> totalConsumed{0};
for (int i = 0; i < NUM_THREADS; ++i) {
producers.emplace_back([&q] {
for (int j = 0; j < OPS_PER_THREAD; ++j) {
q.push(j);
}
});
consumers.emplace_back([&q, &totalConsumed] {
int val;
for (int j = 0; j < OPS_PER_THREAD; ++j) {
if (q.tryPop(val)) {
++totalConsumed;
}
}
});
}
for (auto& t : producers) t.join();
for (auto& t : consumers) t.join();
EXPECT_EQ(totalConsumed, NUM_THREADS * OPS_PER_THREAD);
}
6.2 性能基准测试
比较不同实现的性能差异:
cpp复制#include <chrono>
#include <iostream>
template <typename Queue>
void benchmark(const std::string& name) {
const int OPS = 1000000;
Queue q;
auto start = std::chrono::high_resolution_clock::now();
for (int i = 0; i < OPS; ++i) {
q.enqueue(i);
}
for (int i = 0; i < OPS; ++i) {
q.dequeue();
}
auto end = std::chrono::high_resolution_clock::now();
auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(end - start);
std::cout << name << ": " << duration.count() << " ms\n";
}
int main() {
benchmark<ArrayQueue<int, 1000000>>("ArrayQueue");
benchmark<LinkedListQueue<int>>("LinkedListQueue");
benchmark<LockFreeQueue<int>>("LockFreeQueue");
benchmark<CacheOptimizedQueue<int, 64>>("CacheOptimizedQueue");
return 0;
}
6.3 常见问题排查
队列实现中常见的问题及解决方法:
- 内存泄漏:确保所有动态分配的节点都被正确释放,特别是在异常情况下
- 竞争条件:多线程环境下确保所有共享数据的访问都有适当的同步机制
- 虚假空队列:在检查空队列和实际出队操作之间,其他线程可能已经修改了队列状态
- ABA问题:无锁实现中要特别注意指针重用问题
- 缓存一致性:多核CPU上确保修改对其他核心可见
7. C++20/23新特性在队列中的应用
7.1 使用协程实现异步队列
C++20引入的协程可以简化异步队列的实现:
cpp复制#include <coroutine>
#include <optional>
template <typename T>
class AsyncQueue {
public:
struct promise_type;
using handle_type = std::coroutine_handle<promise_type>;
struct promise_type {
T value;
std::coroutine_handle<> waiter;
AsyncQueue get_return_object() {
return AsyncQueue{handle_type::from_promise(*this)};
}
std::suspend_always initial_suspend() { return {}; }
std::suspend_always final_suspend() noexcept { return {}; }
void return_void() {}
void unhandled_exception() { std::terminate(); }
std::suspend_always yield_value(T val) {
value = std::move(val);
if (waiter) {
waiter.resume();
waiter = nullptr;
}
return {};
}
};
explicit AsyncQueue(handle_type h) : handle(h) {}
void enqueue(T value) {
if (!handle.done()) {
handle.promise().value = std::move(value);
if (handle.promise().waiter) {
handle.promise().waiter.resume();
handle.promise().waiter = nullptr;
}
}
}
struct Awaiter {
promise_type& promise;
bool await_ready() { return false; }
void await_suspend(std::coroutine_handle<> h) {
promise.waiter = h;
}
T await_resume() {
return std::move(promise.value);
}
};
Awaiter operator co_await() {
return Awaiter{handle.promise()};
}
~AsyncQueue() {
if (handle) handle.destroy();
}
private:
handle_type handle;
};
// 使用示例
AsyncQueue<int> createProducer() {
for (int i = 0; i < 10; ++i) {
co_yield i;
}
}
AsyncQueue<int> createConsumer(AsyncQueue<int>& queue) {
for (int i = 0; i < 10; ++i) {
int value = co_await queue;
std::cout << "Received: " << value << std::endl;
}
}
7.2 使用span优化数组队列
C++20的span可以安全地传递数组视图:
cpp复制#include <span>
template <typename T>
class SpanQueue {
private:
std::span<T> buffer;
size_t head = 0;
size_t tail = 0;
size_t count = 0;
public:
explicit SpanQueue(std::span<T> buf) : buffer(buf) {}
bool enqueue(const T& item) {
if (count == buffer.size()) return false;
buffer[tail] = item;
tail = (tail + 1) % buffer.size();
++count;
return true;
}
std::optional<T> dequeue() {
if (count == 0) return std::nullopt;
T item = buffer[head];
head = (head + 1) % buffer.size();
--count;
return item;
}
// 其他接口...
};
7.3 使用format实现调试输出
C++20的format库可以方便地实现队列内容的可视化:
cpp复制#include <format>
#include <iostream>
template <typename T>
void printQueue(const T& queue) {
std::cout << std::format("Queue[size={}, head={}, tail={}]: [",
queue.size(), queue.headIndex(), queue.tailIndex());
for (size_t i = 0; i < queue.size(); ++i) {
if (i > 0) std::cout << ", ";
std::cout << queue.itemAt(i);
}
std::cout << "]\n";
}
8. 队列在算法中的应用
8.1 广度优先搜索(BFS)
队列是BFS算法的核心数据结构:
cpp复制#include <unordered_set>
#include <queue>
template <typename Graph>
std::vector<typename Graph::Node> bfs(const Graph& graph,
typename Graph::Node start) {
using Node = typename Graph::Node;
std::vector<Node> result;
std::queue<Node> q;
std::unordered_set<Node> visited;
q.push(start);
visited.insert(start);
while (!q.empty()) {
Node current = q.front();
q.pop();
result.push_back(current);
for (Node neighbor : graph.neighbors(current)) {
if (visited.insert(neighbor).second) {
q.push(neighbor);
}
}
}
return result;
}
8.2 滑动窗口问题
队列可以高效解决滑动窗口类问题:
cpp复制#include <deque>
std::vector<int> maxSlidingWindow(const std::vector<int>& nums, int k) {
std::vector<int> result;
std::deque<int> dq; // 存储索引
for (int i = 0; i < nums.size(); ++i) {
// 移除超出窗口范围的元素
while (!dq.empty() && dq.front() <= i - k) {
dq.pop_front();
}
// 移除所有小于当前元素的索引
while (!dq.empty() && nums[dq.back()] < nums[i]) {
dq.pop_back();
}
dq.push_back(i);
// 窗口形成后记录最大值
if (i >= k - 1) {
result.push_back(nums[dq.front()]);
}
}
return result;
}
8.3 生产者-消费者模式
队列是生产者-消费者模式的理想选择:
cpp复制#include <thread>
#include <chrono>
template <typename T>
class ProducerConsumer {
private:
ThreadSafeQueue<T> queue;
std::atomic<bool> running{true};
void producer(int id) {
for (int i = 0; running; ++i) {
T item = generateItem(id, i);
queue.push(item);
std::this_thread::sleep_for(std::chrono::milliseconds(10));
}
}
void consumer(int id) {
while (running) {
T item;
if (queue.waitAndPop(item, std::chrono::milliseconds(100))) {
processItem(id, item);
}
}
}
public:
void run(int numProducers, int numConsumers) {
std::vector<std::thread> producers;
std::vector<std::thread> consumers;
for (int i = 0; i < numProducers; ++i) {
producers.emplace_back(&ProducerConsumer::producer, this, i);
}
for (int i = 0; i < numConsumers; ++i) {
consumers.emplace_back(&ProducerConsumer::consumer, this, i);
}
std::this_thread::sleep_for(std::chrono::seconds(10));
running = false;
for (auto& t : producers) t.join();
for (auto& t : consumers) t.join();
}
};
9. 跨平台队列实现考量
9.1 内存模型差异处理
不同平台的内存模型可能影响无锁队列的实现:
cpp复制#if defined(__x86_64__) || defined(_M_X64)
#define MEMORY_BARRIER() std::atomic_thread_fence(std::memory_order_seq_cst)
#elif defined(__aarch64__)
#define MEMORY_BARRIER() __asm__ __volatile__("dmb ish" ::: "memory")
#else
#define MEMORY_BARRIER() std::atomic_thread_fence(std::memory_order_seq_cst)
#endif
template <typename T>
class CrossPlatformQueue {
// 使用MEMORY_BARRIER()确保跨平台内存一致性
};
9.2 原子操作封装
统一不同平台的原子操作接口:
cpp复制template <typename T>
class AtomicWrapper {
private:
std::atomic<T> value;
public:
AtomicWrapper() = default;
explicit AtomicWrapper(T val) : value(val) {}
T load() const {
return value.load(std::memory_order_acquire);
}
void store(T val) {
value.store(val, std::memory_order_release);
}
bool compareAndSwap(T expected, T desired) {
return value.compare_exchange_strong(expected, desired,
std::memory_order_acq_rel);
}
};
9.3 字节序处理
网络应用中需要考虑字节序转换:
cpp复制#include <arpa/inet.h>
class NetworkPacketQueue {
private:
struct PacketHeader {
uint32_t length;
uint32_t checksum;
};
ThreadSafeQueue<std::vector<uint8_t>> queue;
void processPacket(std::vector<uint8_t> data) {
PacketHeader* header = reinterpret_cast<PacketHeader*>(data.data());
header->length = ntohl(header->length);
header->checksum = ntohl(header->checksum);
// 处理数据包...
queue.push(std::move(data));
}
};
10. 现代C++队列设计模式
10.1 策略模式实现多算法队列
cpp复制template <typename T>
class QueueStrategy {
public:
virtual ~QueueStrategy() = default;
virtual void enqueue(T item) = 0;
virtual std::optional<T> dequeue() = 0;
virtual size_t size() const = 0;
};
template <typename T>
class StrategyQueue {
private:
std::unique_ptr<QueueStrategy<T>> strategy;
public:
explicit StrategyQueue(std::unique_ptr<QueueStrategy<T>> strat)
: strategy(std::move(strat)) {}
void enqueue(T item) { strategy->enqueue(item); }
std::optional<T> dequeue() { return strategy->dequeue(); }
size_t size() const { return strategy->size(); }
void setStrategy(std::unique_ptr<QueueStrategy<T>> strat) {
strategy = std::move(strat);
}
};
// 具体策略实现...
10.2 观察者模式实现队列监控
cpp复制template <typename T>
class QueueObserver {
public:
virtual ~QueueObserver() = default;
virtual void onEnqueue(const T& item, size_t newSize) = 0;
virtual void onDequeue(const T& item, size_t newSize) = 0;
};
template <typename T>
class ObservableQueue {
private:
std::queue<T> queue;
std::vector<std::shared_ptr<QueueObserver<T>>> observers;
std::mutex mtx;
public:
void addObserver(std::shared_ptr<QueueObserver<T>> observer) {
std::lock_guard<std::mutex> lock(mtx);
observers.push_back(observer);
}
void enqueue(T item) {
std::lock_guard<std::mutex> lock(mtx);
queue.push(item);
for (auto& obs : observers) {
obs->onEnqueue(item, queue.size());
}
}
T dequeue() {
std::lock_guard<std::mutex> lock(mtx);
T item = queue.front();
queue.pop();
for (auto& obs : observers) {
obs->onDequeue(item, queue.size());
}
return item;
}
};
10.3 工厂模式创建不同类型队列
cpp复制enum class QueueType {
ARRAY,
LINKED_LIST,
LOCK_FREE,
PRIORITY
};
template <typename T>
class QueueFactory {
public:
static std::unique_ptr<QueueStrategy<T>> create(QueueType type, size_t capacity = 0) {
switch (type) {
case QueueType::ARRAY:
return std::make_unique<ArrayQueueStrategy<T>>(capacity);
case QueueType::LINKED_LIST:
return std::make_unique<LinkedListQueueStrategy<T>>();
case QueueType::LOCK_FREE:
return std::make_unique<LockFreeQueueStrategy<T>>();
case QueueType::PRIORITY:
return std::make_unique<PriorityQueueStrategy<T>>();
default:
throw std::invalid_argument("Unknown queue type");
}
}
};
11. 性能调优实战经验
11.1 内存池优化
自定义内存池可以显著提高频繁分配释放场景的性能:
cpp复制class QueueMemoryPool {
private:
struct Block {
void* memory;
Block* next;
};
Block* freeList = nullptr;
std::mutex mtx;
const size_t blockSize;
public:
explicit QueueMemoryPool(size_t itemSize)
: blockSize((itemSize + sizeof(void*) - 1) & ~(sizeof(void*) - 1)) {}
~QueueMemoryPool() {
Block* current = freeList;
while (current) {
Block* next = current->next;
::operator delete(current->memory);
delete current;
current = next;
}
}
void* allocate() {
std::lock_guard<std::mutex> lock(mtx);
if (freeList) {
void* mem = freeList->memory;
Block* next = freeList->next;
delete freeList;
freeList = next;
return mem;
}
return ::operator new(blockSize);
}
void deallocate(void* mem) {
std::lock_guard<std::mutex> lock(mtx);
Block* newBlock = new Block{mem, freeList};
freeList = newBlock;
}
};
template <typename T>
class PooledQueue {
private:
QueueMemoryPool pool;
// 队列实现...
};
11.2 批量操作优化
批量处理可以减少锁竞争和函数调用开销:
cpp复制template <typename T>
class BatchQueue {
private:
std::queue<T> queue;
std::mutex mtx;
std::condition_variable cv;
public:
void enqueueBatch(const std::vector<T>& items) {
std::lock_guard<std::mutex> lock(mtx);
for (const auto& item : items) {
queue.push(item);
}
if (!items.empty()) {
cv.notify_all();
}
}
std::vector<T> dequeueBatch(size_t maxItems) {
std::unique_lock<std::mutex> lock(mtx);
cv.wait(lock, [this]{ return !queue.empty(); });
std::vector<T> result;
while (!queue.empty() && result.size() < maxItems) {
result.push_back(queue.front());
queue.pop();
}
return result;
}
};
11.3 缓存行对齐优化
避免伪共享提高多核性能:
cpp复制template <typename T>
struct CacheLineAligned {
alignas(64) T value;
};
class HighPerfQueue {
private:
struct PaddedAtomic {
alignas(64) std::atomic<size_t> count{0};
};
PaddedAtomic producerCount;
PaddedAtomic consumerCount;
// 其他成员...
};
12. 异常安全与资源管理
12.1 RAII包装器实现
确保资源在任何情况下都能正确释放:
cpp复制template <typename T>
class QueueRAIIWrapper {
private:
T* queue;
public:
explicit QueueRAIIWrapper(T* q) : queue(q) {}
~QueueRAIIWrapper() { delete queue; }
// 禁用拷贝
QueueRAIIWrapper(const QueueRAIIWrapper&) = delete;
QueueRAIIWrapper
