当前位置: 首页 > news >正文

Qt 一次性把多线程实现方式说清楚

一、方式1

1.继承QThread,重写run()方法:

1)QThread 是底层线程管理类,默认run()会调用exec()开启线程事件循环;

2)重写run()函数,调用start()启动线程。

2.测试

CustomThread.h

#ifndef CUSTOMTHREAD_H #define CUSTOMTHREAD_H #include <QThread> #include <QObject> #include <QDebug> //自定义线程类 class CustomThread : public QThread { Q_OBJECT protected: void run() override { qDebug() << "继承QThread 子线程ID:" << QThread::currentThreadId(); //模拟耗时任务 msleep(1000); emit taskFinish(); } signals: void taskFinish(); }; #endif // CUSTOMTHREAD_H

main.cpp

#include <QCoreApplication> #include <QThread> #include <QRunnable> #include <QThreadPool> #include <QtConcurrent/QtConcurrent> #include <QDebug> #include <thread> #include <chrono> #include "CustomThread.h" //在main中调用 void demo_QThread_Inherit() { CustomThread t; QObject::connect(&t, &CustomThread::taskFinish, [](){ qDebug() << "继承QThread任务执行完毕"; }); t.start(); //启动子线程 t.wait(); //主线程阻塞等待线程结束 } int main(int argc, char *argv[]) { QCoreApplication a(argc, argv); qDebug() << "main start"; qDebug() << "主线程ID" << QThread::currentThreadId(); demo_QThread_Inherit(); qDebug() << "main end"; return 0; //return a.exec(); }

二、方式2

1.QObject + moveToThread():

1)创建纯业务工作类(Worker)继承QObject,通过moveToThread(thread)将整个对象移动到子线程事件循环;

2)通过信号槽跨线程通信(Qt 自动队列连接),保证槽函数在子线程执行。

2.测试

Worker.h

#ifndef WORKER_H #define WORKER_H #include <QObject> #include <QThread> #include <QDebug> //工作对象(纯业务,无线程继承) class Worker : public QObject { Q_OBJECT public slots: void doTask(int num) { qDebug() << "moveToThread 子线程ID:" << QThread::currentThreadId() << "参数:" << num; QThread::msleep(1000); emit taskDone(num * 2); } signals: void taskDone(int res); }; #endif // WORKER_H

main.cpp

#include <QCoreApplication> #include <QThread> #include <QRunnable> #include <QThreadPool> #include <QtConcurrent/QtConcurrent> #include <QDebug> #include <thread> #include <chrono> #include "Worker.h" //在main中调用 void demo_moveToThread() { QThread* workThread = new QThread; Worker* worker = new Worker; worker->moveToThread(workThread); //任务启动 QObject::connect(workThread, &QThread::started, worker, [worker](){ worker->doTask(100); }); //任务完成,退出线程 QObject::connect(worker, &Worker::taskDone,[](int res) { qDebug() << "moveToThread 函数执行完毕 res:"<< res; }); //清理内存 QObject::connect(workThread, &QThread::finished, worker, &QObject::deleteLater); QObject::connect(workThread, &QThread::finished, workThread, &QObject::deleteLater); //开启线程 workThread->start(); workThread->quit(); workThread->wait(); //正确阻塞等待线程完全结束 } int main(int argc, char *argv[]) { QCoreApplication a(argc, argv); qDebug() << "main start"; qDebug() << "主线程ID" << QThread::currentThreadId(); demo_moveToThread(); qDebug() << "main end"; return 0; //return a.exec(); }

三、方式3

1.QThreadPool + QRunnable:

1)QRunnable:封装单次任务,QThreadPool 复用线程,避免反复创建销毁线程开销;

2)globalInstance() 使用全局共享线程池,也可创建局部独立线程池;

3)默认自动销毁 QRunnable(autoDelete=true)。

2.测试

main.cpp

#include <QCoreApplication> #include <QThread> #include <QRunnable> #include <QThreadPool> #include <QtConcurrent/QtConcurrent> #include <QDebug> #include <thread> #include <chrono> //任务封装类 class RunTask : public QRunnable { public: explicit RunTask(int id) : m_id(id) {} void run() override { qDebug() << "QThreadPool 任务" << m_id << "线程ID:" << QThread::currentThreadId(); QThread::msleep(800); } private: int m_id; }; //在main中调用 void demo_QRunnable_Pool() { QThreadPool* pool = QThreadPool::globalInstance(); pool->setMaxThreadCount(4); //设置最大并发线程 //提交5个任务,自动复用线程 for(int i = 1; i <= 5; i++) { pool->start(new RunTask(i)); //autoDelete默认true,执行完自动释放 } pool->waitForDone(); // 阻塞等待所有任务完成 qDebug() << "线程池全部任务结束"; } int main(int argc, char *argv[]) { QCoreApplication a(argc, argv); qDebug() << "main start"; qDebug() << "主线程ID" << QThread::currentThreadId(); demo_QRunnable_Pool(); qDebug() << "main end"; return 0; //return a.exec(); }

四、方式4

1.QtConcurrent 高级并发API,需要添加在pro文件中concurrent模块:

1)QtConcurrent模块提供高层并发函数,底层基于QThreadPool,无需手动管理线程;

2)QtConcurrent::run:运行任意函数或lamdba;

3)QtConcurrent::map/filter/reduce:批量容器并行运算;

4)返回QFuture 用于等待/获取结果、进度监控。

2.测试

main.cpp

#include <QCoreApplication> #include <QThread> #include <QRunnable> #include <QThreadPool> #include <QtConcurrent/QtConcurrent> #include <QDebug> #include <thread> #include <chrono> //普通耗时函数 int calcFunc(int a, int b) { qDebug() << "QtConcurrent 普通函数 子线程ID:" << QThread::currentThreadId(); QThread::msleep(1000); return a + b; } void demo_QtConcurrent() { //异步执行函数 QFuture<int> future = QtConcurrent::run(calcFunc, 111, 555); qDebug() << "主线程不阻塞,等待计算..."; future.waitForFinished(); //阻塞等待结果 qDebug() << "QtConcurrent计算结果:" << future.result(); //Lambda版本 QFuture<void> lambdaTask = QtConcurrent::run([](){ qDebug() << "QtConcurrent Lambda 子线程ID" << QThread::currentThreadId(); }); lambdaTask.waitForFinished(); } int main(int argc, char *argv[]) { QCoreApplication a(argc, argv); qDebug() << "main start"; qDebug() << "主线程ID" << QThread::currentThreadId(); demo_QtConcurrent(); qDebug() << "main end"; return 0; //return a.exec(); }

五、方式5

1.C++原生std::thread(非Qt线程模型):

1)直接使用C++标准库std::thread,可运行lambda/普通函数。

2.测试

main.cpp

#include <QCoreApplication> #include <QThread> #include <QRunnable> #include <QThreadPool> #include <QtConcurrent/QtConcurrent> #include <QDebug> #include <thread> #include <chrono> void stdThreadWork(int val) { qDebug() << "std::thread 子线程值:" << val; //阻塞当前线程2秒 std::this_thread::sleep_for(std::chrono::seconds(2)); } void demo_stdThread() { std::thread t1(stdThreadWork, 666); std::thread t2([](){ qDebug() << "std::thread lambda"; }); t1.join(); //等待线程执行完毕 t2.join(); qDebug() << "std::thread全部结束"; } int main(int argc, char *argv[]) { QCoreApplication a(argc, argv); qDebug() << "main start"; qDebug() << "主线程ID" << QThread::currentThreadId(); demo_stdThread(); qDebug() << "main end"; return 0; //return a.exec(); }

http://www.jsqmd.com/news/1205024/

相关文章:

  • Windows蓝屏错误码解析与系统故障排查指南
  • Start11工具:Win11开始菜单个性化定制指南
  • 千问可以生成excel吗?AI导出鸭一键解锁答案
  • dev机器出现Java 应用:OutOfMemoryError: unable to create new native thread
  • GPT 5.6 Sol系统提示词泄露:大语言模型行为机制与提示词工程深度解析
  • Windows 11 24H2与LTSC 2024版本解析与部署指南
  • 3万资金全仓短线交易策略:精准选股与风险控制实战指南
  • 手搓UDS Bootloader|全网独家复现ISO15765 TP网络层、完善单多帧解析分段重组时序管控、助力车载大容量固件无损可靠传输与车规刷写落地
  • Ubuntu 25.10安装与优化全指南
  • 《基于自研主控的工业级eMMC架构解析:如何通过SPOR与pSLC模式解决电力终端掉盘与寿命痛点?》
  • 智能体协作工程:架构设计与实战优化
  • GitHub Copilot Business:企业级AI编码治理平台实战指南
  • VS 2017安装实战指南:工业级遗留系统开发必备IDE
  • MyBatis 操作数据库(⼊⻔)--JDBC 操作
  • AU-60 模组实战,四档拾音距离如何一键切换
  • 开源AI CRM系统:架构解析与智能应用实践
  • 钉钉AI Pro vs 企微AI:一场关于「谁更懂中国企业」的再验证
  • FPGA开发入门:盘古1K按键控制LED实验详解
  • 深入解析blender_mmd_tools:5个核心模块实现MMD模型高效导入
  • 嵌入式DSP实验:AD7606与AD5724数据采集与输出配置详解
  • Cursor实战案例-运维监控-100-全自动镜像清理:利用Shell脚本定时检测并清除Docker无用挂起镜像与策略数据
  • Longan Pi 3H开发板图像采集与AI物体识别实践
  • 智能家居中高端产品技术路线对比分析(2026)
  • 阿里云秒悟Meoo:自然语言生成应用的AI开发平台解析
  • Cocos2d-x中文乱码问题解决方案与优化
  • 智谱清言导出对话全方案盘点,依靠 AI 导出鸭实测各类导出工具,优选高效文档导出路径
  • Mac环境变量配置与Shell加载机制详解
  • Kimi 转 Word 工具推荐?高效便捷的 AI 导出鸭,轻松完成 Kimi 内容转 Word
  • 大模型与知识库结合的Code Review优化实践
  • RAG系列之——Rerank到底解决了什么问题?