51、Move方式创建线程---------多线程

Move方式创建线程

这种方法通过将工作逻辑封装在一个 QObject 派生类中,并将其移动到 QThread 对象中执行。通过信号和槽实现线程间通信。移动过后任务类归属于QThread子线程。

QObject移动到线程的方法

cpp 复制代码
void QObject::moveToThread(QThread *targetThread)

优点:

  • 更加符合 Qt 的信号槽机制。
  • 更容易管理线程生命周期。
  • 提高代码的可维护性和可扩展性。

我们先实现一个自定义的Worker任务类,使其继承自QObject,但是要注意,类的声明一定要包含Q_OBJECT宏

cpp 复制代码
class Worker : public QObject
{
    Q_OBJECT
public:
    //显示构造worker类
    explicit Worker(QObject *parent = nullptr);
signals:

public slots:
    //响应线程started信号
    void doWork();
signals:
    //任务完成后发出这个信号
    void finished();
};

实现构造函数

cpp 复制代码
Worker::Worker(QObject *parent) : QObject(parent)
{

}

实现开始任务的槽函数

cpp 复制代码
void Worker::doWork()
{
    qDebug() << "工作线程开始:" << QThread::currentThreadId();
    for(int i = 0; i < 5; i++){
        qDebug() << "计数:" << i;
        QThread::sleep(1); // 模拟耗时操作
    }
    //发送结束信号
    emit finished();
    qDebug() << "工作线程结束:" << QThread::currentThreadId();
}

在主函数中创建一个线程,并且将这个任务类移交给线程

注意

被移交的类一定不能有父窗口

cpp 复制代码
    //创建一个新的线程
    QThread* worker_thread = new QThread();
    //创建任务类
    Worker* worker = new Worker();

    //将worker移动到线程里
    worker->moveToThread(worker_thread);

因为我们要通过线程的信号通知任务类开始工作,以及任务类要通过完成信号通知线程退出等,这里先列举几个信号

QThread线程开始信号,该信号在调用QThread的start()方法后由QThread发出

cpp 复制代码
[signal] void QThread::started()

QThread线程结束信号,在线程调用quit()或者正常退出时发出这个信号

cpp 复制代码
[signal] void QThread::finished()

我们先捕获线程的开始信号, 因为连接信号不是在QObject类里,所以显示调用QObject作用域连接

cpp 复制代码
//连接线程开始信号
QObject::connect(worker_thread,&QThread::started,worker,&Worker::doWork);

所有QObject都有一个deleteLater槽函数

cpp 复制代码
[slot] void QObject::deleteLater()

捕获线程退出信号,连接线程自己的deleteLater槽函数,

cpp 复制代码
//连接线程退出信号和回收槽函数
QObject::connect(worker_thread, &QThread::finished, worker_thread, &QThread::deleteLater);

连接worker退出信号和回收槽函数

cpp 复制代码
//连接worker退出信号和回收槽函数
QObject::connect(worker,&Worker::finished,worker,&Worker::deleteLater);

启动线程

cpp 复制代码
//启动线程
worker_thread->start();

完整版代码

cpp 复制代码
int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    
    //创建一个新的线程
    QThread* worker_thread = new QThread();
    //创建任务类
    Worker* worker = new Worker();

    //将worker移动到线程里
    worker->moveToThread(worker_thread);

    //连接线程开始信号
    QObject::connect(worker_thread,&QThread::started,worker,&Worker::doWork);

    //连接任务类结束信号,调用线程退出信号
    QObject::connect(worker,&Worker::finished, worker_thread, &QThread::quit);

    //连接线程退出信号和回收槽函数
    QObject::connect(worker_thread, &QThread::finished, worker_thread, &QThread::deleteLater);

    //连接worker退出信号和回收槽函数
    QObject::connect(worker,&Worker::finished,worker,&Worker::deleteLater);

    //启动线程
    worker_thread->start();
    MainWindow mainwindow;
    mainwindow.show();
    //等待任务执行完成退出
    return a.exec();
}

程序运行后,输出

bash 复制代码
工作线程开始: 0x4124
计数: 0
计数: 1
计数: 2
计数: 3
计数: 4
工作线程结束: 0x4124

因为a.exec()还在等待其他事件处理,所以主线程不会退出。

相关推荐
jinyishu_10 小时前
模拟实现 C++ 栈和队列——从适配器模式看懂 STL 容器之美
java·c++·适配器模式
hehelm10 小时前
AI大模型接入SDK—通用模块设计
linux·开发语言·c++
hold?fish:palm12 小时前
RDB全量快照备份
c++·redis·后端
盐焗鹌鹑蛋14 小时前
【C++】C++11:列表初始化、声明、STL升级
c++
ComputerInBook15 小时前
c 和 c++ 中的宏块(macro)
c语言·c++··宏块·宏指令
AA陈超16 小时前
004 T02 - 俯视角摄像机系统 设计文档
网络·c++·ue5·虚幻引擎
bu_shuo16 小时前
c与cpp中的argc和argv
c语言·c++·算法
蓝创精英团队16 小时前
VCPKG 跨平台C++ 库管理器
c++·vcpkg
Jayden_Ruan18 小时前
C++组合的输出
c++·算法·深度优先
froyoisle18 小时前
CSP 真题解析:[CSP-J 2020-T3] 表达式
c++·算法·csp·信息学·信奥赛