C++ std::queue:高效处理先入先出的数据
在程序世界里,很多场景都需要按照 “先来后到” 的规则处理数据 —— 比如打印任务排队、消息队列传递数据、广度优先搜索中的节点遍历。这时,std::queue就能派上大用场,它像一条两端通透的管道,数据从一端进入,从另一端按顺序流出,完美贴合 “先入先出” 的业务需求。
先看一个简单的打印任务模拟,感受std::queue的基本用法:
#include <iostream>
#include <queue>
#include <string>
using namespace std;
int main() {
// 创建一个存储字符串的队列,模拟打印任务列表
queue<string> print_tasks;
// 添加打印任务(入队操作)
print_tasks.push("简历.pdf");
print_tasks.push("报告.docx");
print_tasks.push("图片.png");
// 查看队列中有多少任务
cout << "当前等待打印的任务数:" << print_tasks.size() << endl;
// 处理任务(出队操作),按添加顺序依次处理
while (!print_tasks.empty()) {
// 查看队首任务(不删除)
cout << "正在打印:" << print_tasks.front() << endl;
// 移除队首任务(已完成)
print_tasks.pop();
}
// 确认队列已空
if (print_tasks.empty()) {
cout << "所有打印任务已完成!" << endl;
}
return 0;
}
这段代码清晰展示了std::queue的核心操作:push()添加元素到队尾,front()获取队首元素,pop()移除队首元素,size()查看元素数量,empty()判断队列是否为空。这些操作组合起来,就能轻松实现各种排队场景。
std::queue的内部结构默认基于std::deque实现,这让它在两端操作时效率极高。如果你需要严格控制内存分配,也可以指定其他底层容器,只要该容器支持back()、push_back()、front()、pop_front()和empty()操作即可,比如用std::list作为底层:
// 使用list作为底层容器的队列
queue<int, list<int>> custom_queue;
custom_queue.push(10);
custom_queue.push(20);
cout << custom_queue.front() << endl; // 输出10
在多线程通信中,std::queue常被用来实现生产者 - 消费者模型。比如一个线程生成数据(生产者),另一个线程处理数据(消费者),队列就像两者之间的缓冲区:
#include <thread>
#include <mutex>
#include <condition_variable>
queue<int> data_queue;
mutex mtx;
condition_variable cv;
bool finished = false;
// 生产者:生成数据并放入队列
void producer() {
for (int i = 0; i < 5; ++i) {
{
lock_guard<mutex> lock(mtx);
data_queue.push(i);
cout << "生产数据:" << i << endl;
}
cv.notify_one(); // 通知消费者有新数据
this_thread::sleep_for(chrono::milliseconds(100));
}
// 标记生产结束
{
lock_guard<mutex> lock(mtx);
finished = true;
}
cv.notify_one();
}
// 消费者:从队列中取出数据并处理
void consumer() {
while (true) {
unique_lock<mutex> lock(mtx);
// 等待数据或生产结束
cv.wait(lock, []{ return !data_queue.empty() || finished; });
// 如果生产结束且队列空,则退出
if (finished && data_queue.empty()) break;
// 处理数据
while (!data_queue.empty()) {
cout << "消费数据:" << data_queue.front() << endl;
data_queue.pop();
}
}
}
int main() {
thread prod(producer);
thread cons(consumer);
prod.join();
cons.join();
return 0;
}
这个例子中,队列安全地在两个线程间传递数据,配合互斥锁和条件变量,完美解决了生产者和消费者的协作问题。
std::queue的设计哲学是 “简单专一”—— 它只提供必要的接口,隐藏了复杂的实现细节。这种特性让它在处理排队场景时既高效又易用,避免了手动实现队列时容易出现的内存泄漏、越界访问等问题。无论是模拟现实中的排队场景,还是实现程序内部的缓冲机制,std::queue都能以简洁的代码完成任务,是 C++ 开发者处理顺序数据的得力工具。