Qt 多线程编程 #
多线程概述 #
text
┌─────────────────────────────────────────────────────────────┐
│ Qt 多线程方式 │
├─────────────────────────────────────────────────────────────┤
│ │
│ QThread │
│ ├── 底层线程类 │
│ ├── 继承或 moveToThread │
│ └── 最灵活但需要更多代码 │
│ │
│ QtConcurrent │
│ ├── 高级并发 API │
│ ├── 自动管理线程池 │
│ └── 适合简单并行任务 │
│ │
│ QThreadPool / QRunnable │
│ ├── 线程池和可运行对象 │
│ ├── 复用线程资源 │
│ └── 适合大量短任务 │
│ │
└─────────────────────────────────────────────────────────────┘
QThread 基本使用 #
方式一:继承 QThread #
cpp
class WorkerThread : public QThread
{
Q_OBJECT
public:
WorkerThread(QObject *parent = nullptr) : QThread(parent) {}
protected:
void run() override
{
// 在新线程中执行的代码
for (int i = 0; i < 100; ++i) {
if (isInterruptionRequested()) {
break; // 响应中断请求
}
emit progressChanged(i);
QThread::msleep(100);
}
emit workFinished();
}
signals:
void progressChanged(int percent);
void workFinished();
};
// 使用
WorkerThread *thread = new WorkerThread(this);
connect(thread, &WorkerThread::progressChanged, [](int percent) {
qDebug() << "Progress:" << percent;
});
connect(thread, &WorkerThread::workFinished, []() {
qDebug() << "Finished";
});
connect(thread, &WorkerThread::finished, thread, &QObject::deleteLater);
thread->start(); // 启动线程
// 停止线程
thread->requestInterruption();
thread->wait(); // 等待线程结束
方式二:moveToThread(推荐) #
cpp
class Worker : public QObject
{
Q_OBJECT
public:
explicit Worker(QObject *parent = nullptr) : QObject(parent) {}
public slots:
void doWork(int parameter)
{
// 在工作线程中执行
for (int i = 0; i < 100; ++i) {
if (QThread::currentThread()->isInterruptionRequested()) {
break;
}
emit progressChanged(i);
QThread::msleep(100);
}
emit workFinished();
}
signals:
void progressChanged(int percent);
void workFinished();
};
// 使用
class Controller : public QObject
{
Q_OBJECT
public:
Controller() {
Worker *worker = new Worker;
worker->moveToThread(&workerThread);
connect(&workerThread, &QThread::finished, worker, &QObject::deleteLater);
connect(this, &Controller::startWork, worker, &Worker::doWork);
connect(worker, &Worker::progressChanged, this, &Controller::onProgress);
connect(worker, &Worker::workFinished, this, &Controller::onFinished);
workerThread.start();
}
~Controller() {
workerThread.requestInterruption();
workerThread.quit();
workerThread.wait();
}
void start() {
emit startWork(42);
}
signals:
void startWork(int parameter);
private slots:
void onProgress(int percent) {
qDebug() << "Progress:" << percent;
}
void onFinished() {
qDebug() << "Finished";
}
private:
QThread workerThread;
};
线程同步 #
QMutex 互斥锁 #
cpp
class Counter
{
public:
void increment() {
QMutexLocker locker(&m_mutex); // RAII 方式
++m_value;
}
void decrement() {
QMutexLocker locker(&m_mutex);
--m_value;
}
int value() const {
QMutexLocker locker(&m_mutex);
return m_value;
}
private:
mutable QMutex m_mutex;
int m_value = 0;
};
// 手动加锁
QMutex mutex;
mutex.lock();
// 临界区代码
mutex.unlock();
// 尝试加锁
if (mutex.tryLock()) {
// 获取锁成功
mutex.unlock();
}
QReadWriteLock 读写锁 #
cpp
class SharedData
{
public:
QString read() const {
QReadLocker locker(&m_lock);
return m_data;
}
void write(const QString &data) {
QWriteLocker locker(&m_lock);
m_data = data;
}
private:
mutable QReadWriteLock m_lock;
QString m_data;
};
QSemaphore 信号量 #
cpp
// 生产者-消费者示例
const int BufferSize = 10;
QSemaphore freeSpace(BufferSize); // 空闲空间
QSemaphore usedSpace(0); // 已用空间
void producer()
{
for (int i = 0; i < 100; ++i) {
freeSpace.acquire(); // 等待空闲空间
// 生产数据
produceData(i);
usedSpace.release(); // 增加已用空间
}
}
void consumer()
{
for (int i = 0; i < 100; ++i) {
usedSpace.acquire(); // 等待数据
// 消费数据
consumeData();
freeSpace.release(); // 增加空闲空间
}
}
QWaitCondition 条件变量 #
cpp
QMutex mutex;
QWaitCondition condition;
bool ready = false;
// 等待线程
void waitForCondition()
{
QMutexLocker locker(&mutex);
while (!ready) {
condition.wait(&mutex); // 释放锁并等待
}
// 条件满足,继续执行
}
// 唤醒线程
void setCondition()
{
QMutexLocker locker(&mutex);
ready = true;
condition.wakeAll(); // 唤醒所有等待线程
// 或 condition.wakeOne(); // 唤醒一个线程
}
QtConcurrent 并发编程 #
QtConcurrent::run #
cpp
#include <QtConcurrent>
// 在线程池中运行函数
QFuture<int> future = QtConcurrent::run([]() {
// 耗时操作
QThread::sleep(2);
return 42;
});
// 等待结果
int result = future.result();
qDebug() << "Result:" << result;
// 检查是否完成
if (future.isFinished()) {
qDebug() << "Finished";
}
// 使用 QFutureWatcher 监控
QFutureWatcher<int> *watcher = new QFutureWatcher<int>(this);
connect(watcher, &QFutureWatcher<int>::finished, []() {
qDebug() << "Task finished";
});
connect(watcher, &QFutureWatcher<int>::resultReadyAt, [](int index) {
qDebug() << "Result ready at" << index;
});
watcher->setFuture(future);
QtConcurrent::map #
cpp
// 并行映射
QList<int> list = {1, 2, 3, 4, 5};
// 对每个元素应用函数
QFuture<void> future = QtConcurrent::map(list, [](int &value) {
value *= 2; // 修改原列表
});
future.waitForFinished();
qDebug() << list; // {2, 4, 6, 8, 10}
// mapped - 返回新列表
QList<int> doubled = QtConcurrent::mapped(list, [](int value) {
return value * 2;
});
// mappedReduced - 映射并归约
int sum = QtConcurrent::mappedReduced(list,
[](int value) { return value * 2; }, // 映射函数
[](int &result, int value) { result += value; } // 归约函数
);
QtConcurrent::filter #
cpp
QList<int> list = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
// 过滤(修改原列表)
QFuture<void> future = QtConcurrent::filter(list, [](int value) {
return value % 2 == 0; // 保留偶数
});
future.waitForFinished();
qDebug() << list; // {2, 4, 6, 8, 10}
// filtered - 返回新列表
QList<int> evens = QtConcurrent::filtered(list, [](int value) {
return value % 2 == 0;
});
QThreadPool 线程池 #
基本使用 #
cpp
class MyRunnable : public QRunnable
{
public:
MyRunnable(int id) : m_id(id) {
setAutoDelete(true); // 自动删除
}
void run() override {
qDebug() << "Task" << m_id << "running in thread"
<< QThread::currentThread();
QThread::sleep(1);
qDebug() << "Task" << m_id << "finished";
}
private:
int m_id;
};
// 使用全局线程池
for (int i = 0; i < 10; ++i) {
QThreadPool::globalInstance()->start(new MyRunnable(i));
}
// 等待所有任务完成
QThreadPool::globalInstance()->waitForDone();
// 自定义线程池
QThreadPool pool;
pool.setMaxThreadCount(4); // 最大线程数
for (int i = 0; i < 10; ++i) {
pool.start(new MyRunnable(i));
}
pool.waitForDone();
线程安全队列 #
cpp
template<typename T>
class ThreadSafeQueue
{
public:
void enqueue(const T &value) {
QMutexLocker locker(&m_mutex);
m_queue.enqueue(value);
m_condition.wakeOne();
}
T dequeue() {
QMutexLocker locker(&m_mutex);
while (m_queue.isEmpty()) {
m_condition.wait(&m_mutex);
}
return m_queue.dequeue();
}
bool isEmpty() const {
QMutexLocker locker(&m_mutex);
return m_queue.isEmpty();
}
private:
mutable QMutex m_mutex;
QWaitCondition m_condition;
QQueue<T> m_queue;
};
线程最佳实践 #
避免阻塞主线程 #
cpp
// 错误:在主线程执行耗时操作
void onButtonClicked() {
heavyOperation(); // 阻塞 UI
}
// 正确:在工作线程执行
void onButtonClicked() {
QtConcurrent::run([this]() {
heavyOperation();
QMetaObject::invokeMethod(this, "onOperationFinished",
Qt::QueuedConnection);
});
}
正确处理线程退出 #
cpp
class WorkerThread : public QThread
{
public:
~WorkerThread() {
requestInterruption();
quit();
wait(); // 等待线程结束
}
protected:
void run() override {
while (!isInterruptionRequested()) {
// 执行任务
}
}
};
使用信号槽跨线程通信 #
cpp
// 跨线程信号槽自动使用队列连接
connect(worker, &Worker::dataReady,
receiver, &Receiver::processData,
Qt::QueuedConnection); // 数据会被复制
下一步 #
现在你已经掌握了多线程编程,接下来学习 模型/视图架构,了解 Qt 的数据展示架构!
最后更新:2026-03-29