嵌入式Linux下QT应用中Boost实现非QT后台线程事件处理方案咨询
最优实现方案
基于你的需求(非QT对象后台线程等待事件,触发后交由QT线程处理),结合QT线程通信机制与Boost库,最优方案是利用QT的跨线程调用机制实现线程安全的事件通知,同时保持原有类结构的低侵入性。
核心思路
- 让
MainClass(QT线程)启动事件循环,确保能处理跨线程请求; secondClass用Boost.Thread启动后台线程等待事件,触发时通过QMetaObject::invokeMethod在MainClass的线程上下文调用处理函数,避免线程竞争;- 保证线程资源的优雅释放,避免泄漏。
具体代码实现
1. 改造MainClass(QT线程)
让它启动事件循环,并提供可跨线程调用的事件处理函数:
#include <QThread> #include <QDebug> class MainClass : public QThread { Q_OBJECT public: MainClass(QObject *parent = nullptr) : QThread(parent) {} protected: void run() override { // 启动QT事件循环,必须调用此函数才能处理跨线程的invoke请求 exec(); } public slots: void processEvent() { // 事件处理逻辑,确保在MainClass线程执行 qDebug() << "事件处理线程ID:" << QThread::currentThreadId(); // 替换为你的实际处理代码 } };
2. 实现secondClass(非QT对象)
用Boost.Thread启动后台线程,等待事件并触发跨线程调用:
#include <boost/thread.hpp> #include <boost/shared_ptr.hpp> #include <boost/weak_ptr.hpp> #include <QMetaObject> #include <QThread> class secondClass { public: // 传入MainClass的智能指针,用weak_ptr避免悬空引用 secondClass(boost::shared_ptr<MainClass> mainPtr) : m_mainClass(mainPtr) { // 启动后台等待线程 m_workerThread = boost::thread(&secondClass::waitForEvent, this); } ~secondClass() { // 优雅终止后台线程 m_stopFlag = true; if (m_workerThread.joinable()) { m_workerThread.join(); } } private: boost::weak_ptr<MainClass> m_mainClass; boost::thread m_workerThread; bool m_stopFlag = false; void waitForEvent() { qDebug() << "后台等待线程启动,线程ID:" << boost::this_thread::get_id(); while (!m_stopFlag) { // 替换为你的实际事件等待逻辑(如阻塞串口读取、信号量等待等) boost::this_thread::sleep_for(boost::chrono::seconds(3)); // 事件触发,通知MainClass处理 auto mainPtr = m_mainClass.lock(); if (mainPtr) { // 用QueuedConnection确保在MainClass线程执行处理函数 QMetaObject::invokeMethod(mainPtr.get(), "processEvent", Qt::QueuedConnection); } } qDebug() << "后台等待线程退出"; } };
3. 主函数调整
确保MainClass先启动线程,再初始化secondClass:
#include <QApplication> #include <boost/shared_ptr.hpp> boost::shared_ptr<MainClass> mainClass; boost::shared_ptr<secondClass> secondClass; int main(int argc, char *argv[]) { QApplication app(argc, argv); // 初始化并启动MainClass线程 mainClass = boost::make_shared<MainClass>(); mainClass->start(); // 初始化secondClass,传入MainClass指针 secondClass = boost::make_shared<secondClass>(mainClass); // 你的QT应用其他逻辑(如窗口显示等) return app.exec(); } // QT项目需包含moc生成文件,或在pro文件中自动处理 #include "main.moc"
方案优势
- 线程安全:通过
Qt::QueuedConnection确保事件处理在MainClass的线程上下文执行,完全符合QT线程模型,避免数据竞争; - 低侵入性:无需修改
secondClass的继承关系(保持非QT对象),仅需传入MainClass的智能指针; - 资源安全:
secondClass析构时会优雅终止并join后台线程,避免资源泄漏; - 可靠性:用
weak_ptr避免MainClass提前销毁导致的悬空指针问题。
内容的提问来源于stack exchange,提问作者Alex
相关产品推荐
相关产品推荐

