C++ Qt线程读取主线程队列报错?如何安全访问共享队列
多线程访问共享队列的线程安全修复方案
你的问题核心是多线程操作共享队列tickQue时缺少同步机制,导致读线程访问空队列报错。On_Tick在一个线程写入队列,startHighAG在另一个线程读取,两者没有互斥控制,会出现竞态条件——读线程可能在队列还没写入数据时就执行back(),触发空队列错误。
修复步骤:
1. 恢复并正确使用互斥锁
给共享资源(tickQue和AGstart)加锁,确保同一时间只有一个线程能访问它们。
修改startHighAG函数:
void HighAG::startHighAG(int num) { qDebug() << " Thread start" << " || " << QThread::currentThread(); while (true) { QMutexLocker locker(&lock); // 自动加锁,离开作用域自动解锁 // 先检查停止标志,避免空转 if (!AGstart) { break; } qDebug() << "Thread running "; // 必须先判断队列非空,再访问back() if (!tickQue.empty()) { qDebug() << "*****Thread startHighAG::OnTick:" << tickQue.back().askPrice1; } else { qDebug() << "Queue is empty, no data available"; } // 提前解锁,避免sleep期间占用锁导致写线程阻塞 locker.unlock(); QThread::sleep(1); } qDebug() << "Stopped " ; }
修改On_Tick函数:
void HighAG::On_Tick(std::shared_ptr<QuoteInfo> quote) { QMutexLocker locker(&lock); // 加锁保护队列写入操作 tickQue.push(*quote); qDebug() << "startHighAG::OnTick:" << tickQue.back().askPrice1; locker.unlock(); // 提前解锁,避免emit信号时占用锁 emit sendTick(tickQue); }
2. 补充类成员变量声明
在HighAG的头文件中,添加互斥锁和启动标志的成员变量:
class HighAG : public QObject { Q_OBJECT private: QMutex lock; // 保护共享资源的互斥锁 bool AGstart = true; // 线程启动标志,默认初始化true std::queue<QuoteInfo> tickQue; // 你的共享队列 // ...其他成员变量 public slots: void startHighAG(int num); void On_Tick(std::shared_ptr<QuoteInfo> quote); signals: void sendTick(std::queue<QuoteInfo>); };
3. 关键注意事项
- 空队列检查不可少:就算加了锁,读线程也可能比写线程先启动,此时队列为空,必须先判断
!tickQue.empty()再访问back(),否则会触发未定义行为。 - 锁粒度要合理:sleep前解锁,避免写线程在整个sleep期间无法写入队列,导致数据延迟或堆积。
AGstart必须受锁保护:如果有其他线程修改AGstart的值(比如停止线程),修改操作也要在锁的保护下进行,确保内存可见性,避免读线程看不到最新的停止标志。
内容的提问来源于stack exchange,提问作者STAN H
相关产品推荐
相关产品推荐

