方法1:循环弹出元素
cpp
#include <concurrentqueue.h>
// 如果存储的是指针类型
moodycamel::ConcurrentQueue<int*> queue;
int* item = nullptr;
while (queue.try_dequeue(item)) {
if (item) {
delete item; // 如果需要释放内存
item = nullptr;
}
}
// 如果存储的是普通类型
moodycamel::ConcurrentQueue<int> queue;
int item;
while (queue.try_dequeue(item)) {
// 元素自动销毁
}
方法2:批量弹出
cpp
#include <concurrentqueue.h>
#include <vector>
moodycamel::ConcurrentQueue<int> queue;
// 批量弹出,效率更高
std::vector<int> temp;
queue.try_dequeue_bulk(std::back_inserter(temp),
queue.size_approx());
// temp现在包含所有弹出的元素,随后会被自动销毁
temp.clear(); // 立即释放内存
方法3:使用交换技巧、或 std::move(...)
cpp
// 最简单的方法:创建新队列替换旧队列
moodycamel::ConcurrentQueue<int> newQueue;
std::swap(queue, newQueue);
// 原队列的所有权转移到了newQueue,出作用域时自动销毁
方法4:自定义清空函数(模板)
cpp
template<typename T>
void ClearConcurrentQueue(moodycamel::ConcurrentQueue<T>& queue) {
T item;
while (queue.try_dequeue(item)) {
// 元素自动处理
}
}
// 对于指针类型的特化版本
template<typename T>
void ClearConcurrentQueue(moodycamel::ConcurrentQueue<T*>& queue) {
T* item = nullptr;
while (queue.try_dequeue(item)) {
delete item;
item = nullptr;
}
}
线程安全
并发队列,在清空过程中可能有其他线程继续插入元素。如果需要完全清空:
- 暂停生产者:确保没有线程在插入
- 使用原子标志:协调清空操作
- 多次清空:循环清空直到确认队列为空
cpp
// 确保队列完全清空的稳健方法
void EnsureQueueEmpty(moodycamel::ConcurrentQueue<int>& queue) {
int item;
int emptyCount = 0;
const int MAX_EMPTY_CHECKS = 3;
while (emptyCount < MAX_EMPTY_CHECKS) {
if (queue.try_dequeue(item)) {
emptyCount = 0; // 重置计数器
} else {
emptyCount++;
std::this_thread::yield(); // 让出CPU
}
}
}