Qt多线程之moveToThread

Qt多线程之moveToThread


箴言:

小池》 — 杨万里

泉眼无声惜细流,

树阴照水爱晴柔。

小荷才露尖尖角,

早有蜻蜓立上头

介绍

在 Qt 多线程体系中,QObject::moveToThread 是最核心、也是最容易被误用的机制之一。
很多开发者会误以为它是“把代码搬到线程执行”,但实际上:

moveToThread 并不会改变函数调用行为,而是改变对象的线程归属,从而影响事件调度。

1. 基础用法

worker->moveToThread(thread);

实际上等于:

worker->d_ptr->threadData = thread->d_ptr->data;
class MyWork1 : public QObject
{
    Q_OBJECT
public:
    void doWork()
    {
        qDebug() << "Thread:" << reinterpret_cast<quintptr>(QThread::currentThreadId());
    }
};
int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    qDebug() << "主线程: " << quint64(QThread::currentThreadId());

    QThread* thread = new QThread;
    MyWork1* worker = new MyWork1;
    worker->moveToThread(thread);
    QObject::connect(thread, &QThread::started, worker, &MyWork1::doWork);
    thread->start();

    qDebug() << "Exit...";

    return a.exec();
}

主线程:  13300
Exit...
Thread: 20832

worker->doWork(); // 这是普通 C++ 函数调用,不经过 Qt 事件系统, 这样调用,不属于子线程调用。

高频任务处理

#pragma once
#include <QObject>
#include <QThread>
#include <atomic>
#include <QDebug>

#include "USafedQueue.h"


// 假设算法输入输出类型
struct AlgorithmInput {
    int data;
};

struct AlgorithmResult {
    int result;
};


class Worker : public QObject
{
    Q_OBJECT
public:
    Worker(USafedQueue<AlgorithmInput>* queue)
        : m_queue(queue) {}

public slots:
    void process()
    {
        while (!m_stop)
        {
            AlgorithmInput input;
            if (!m_queue->waitPop(input))
            {
                // 队列空且停止标志
                continue;
            }

            // 模拟耗时计算
            AlgorithmResult result;
            result.result = heavyAlgorithm(input);

            // 发射结果信号回主线程
            emit resultReady(result);
        }
    }

    void stop() 
    {
        m_stop = true;
        m_queue->stop();
    }

signals:
    void resultReady(const AlgorithmResult& result);

private:
    ThreadSafeQueue<AlgorithmInput>* m_queue;
    std::atomic_bool m_stop{false};

    // 模拟耗时算法
    int heavyAlgorithm(const AlgorithmInput& input) 
    {
        QThread::msleep(50); // 模拟耗时 50ms
        return input.data * 2; // 举例
    }
};

posted on 2026-04-04 22:38  Hakuon  阅读(37)  评论(0)    收藏  举报