C++队列与线程程序异常退出问题求助
C++多线程队列操作崩溃问题修复
实现目标
我想编写一个程序,在子线程中每秒向queue添加一个元素,主线程每两秒删除一个队列元素并显示队列的大小、队首和队尾数据。
原代码
#include <iostream> #include <queue> #include <thread> #include <Windows.h> using std::queue; using std::cout; void loadQueue(queue<int>& toLoad) { for(int i = 0; i < 100; i++) { toLoad.push(i); Sleep(1000); } } int main(void) { queue<int>toLoad; std::thread(loadQueue, std::ref(toLoad)); while(true) { cout << "SIZE OF QUEUE : " << toLoad.size() << '\n' << '\n'; cout <<"FRONT :" << toLoad.front() << '\n' << '\n'; cout <<"BACK : " << toLoad.back() << '\n'; toLoad.pop(); Sleep(2000); } }
错误情况
程序启动后无任何输出,直接崩溃关闭。Visual Studio抛出的异常信息为:
Unhandled exception at 0x00007FF8B7C4A839 in Project1.exe: Microsoft C++ exception: std::underflow_error at memory location 0x0000004E7C1FE6D0.
问题分析
- 空队列非法访问:主线程启动后立即进入循环,调用
toLoad.front()、toLoad.back()和toLoad.pop(),但子线程需要1秒才会添加第一个元素,此时队列为空,触发std::underflow_error异常导致崩溃。 - 线程安全问题:
std::queue不是线程安全容器,子线程的push操作和主线程的size/front/back/pop操作同时进行会引发数据竞争,属于未定义行为。
修复方案
通过互斥锁和条件变量实现线程同步,确保主线程仅在队列非空时操作,同时保护队列的所有访问操作:
#include <iostream> #include <queue> #include <thread> #include <Windows.h> #include <mutex> #include <condition_variable> using std::queue; using std::cout; using std::mutex; using std::condition_variable; using std::unique_lock; mutex queue_mutex; condition_variable cv; void loadQueue(queue<int>& toLoad) { for(int i = 0; i < 100; i++) { { unique_lock<mutex> lock(queue_mutex); toLoad.push(i); } cv.notify_one(); // 通知主线程队列有新元素 Sleep(1000); } cv.notify_one(); // 子线程结束前通知一次,避免主线程永久等待 } int main(void) { queue<int> toLoad; std::thread loader(loadQueue, std::ref(toLoad)); loader.detach(); // 主线程是死循环,分离子线程 while(true) { unique_lock<mutex> lock(queue_mutex); // 等待队列非空,避免虚假唤醒 cv.wait(lock, [&toLoad](){ return !toLoad.empty(); }); cout << "SIZE OF QUEUE : " << toLoad.size() << "\n\n"; cout << "FRONT :" << toLoad.front() << "\n\n"; cout << "BACK : " << toLoad.back() << "\n"; toLoad.pop(); lock.unlock(); // 解锁后再休眠,避免阻塞子线程的push操作 Sleep(2000); } }
修复说明
- 互斥锁
std::mutex:确保同一时间只有一个线程访问队列,杜绝数据竞争。 - 条件变量
std::condition_variable:让主线程在队列为空时进入等待状态,直到子线程添加元素后唤醒它,彻底解决空队列访问问题。 - 解锁时机优化:在休眠前解锁互斥锁,让子线程可以继续向队列添加元素,提升并发效率。
内容的提问来源于stack exchange,提问作者Michael
相关产品推荐
相关产品推荐

