并发与多线程
# 02.并发与多线程
# 目录介绍
- 2.1 QT线程核心
- 2.1.1 QT线程介绍
- 2.1.2 线程管理类
- 2.1.3 同步原语类
- 2.2 线程管理基础
- 2.2.1 QThread类
- 2.2.2 线程与事件循环
- 2.2.3 线程安全
- 2.3 QThread创建
- 2.3.1 继承QThread
- 2.3.2 moveToThread
- 2.4 多线程编程
- 2.4.1 并行计算
- 2.4.2 并行映射
- 2.5 线程同步
- 2.5.1 互斥锁QMutex
- 2.5.2 QReadWriteLock
- 2.5.3 QSemaphore
- 2.5.4 QWaitCondition
- 2.5.5 QAtomic
# 2.1 QT线程核心
# 2.1.1 QT线程介绍
Qt 提供了强大的线程管理功能,支持多线程编程。Qt 的线程管理基于 QThread 类,同时提供了高级 API(如 QtConcurrent)来简化多线程编程。
# 2.1.2 线程管理类
- QThread:平台无关的线程类
- QThreadPool:线程池管理
- QRunnable:可在线程池中运行的任务基类
- QFuture/QFutureWatcher:异步计算模型
- QPromise:配合 QFuture 使用(Qt 6)
# 2.1.3 同步原语类
- QMutex/QMutexLocker:互斥锁
- QReadWriteLock:读写锁
- QSemaphore:信号量
- QWaitCondition:条件变量
- QAtomic*:原子操作类
# 2.2 线程管理基础
# 2.2.1 QThread类
QThread 是 Qt 中用于管理线程的类。每个 QThread 对象代表一个线程,可以通过 start() 启动线程。
QThread 的 run() 方法是线程的入口点,默认实现调用 exec() 进入事件循环。
# 2.2.2 线程与事件循环
Qt 的事件循环(QEventLoop)是线程的核心,用于处理信号与槽、定时器、网络事件等。
默认情况下,QThread 会启动一个事件循环。
# 2.2.3 线程安全
Qt 提供了线程安全的信号与槽机制,支持跨线程通信。 使用 Qt::QueuedConnection 实现跨线程的信号与槽连接。
# 2.3 QThread创建
# 2.3.1 继承QThread
通过继承 QThread 并重写 run() 方法来实现自定义线程逻辑。
#include <QThread>
#include <QDebug>
class MyThread : public QThread {
Q_OBJECT
protected:
void run() override {
qDebug() << "Thread started";
// 线程逻辑
QThread::sleep(2);
qDebug() << "Thread finished";
}
};
int main(int argc, char *argv[]) {
QCoreApplication app(argc, argv);
MyThread thread;
thread.start(); // 启动线程
thread.wait(); // 等待线程结束
return app.exec();
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# 2.3.2 moveToThread
将 QObject 对象移动到另一个线程,利用信号与槽机制实现线程逻辑。
#include <QThread>
#include <QDebug>
class Worker : public QObject {
Q_OBJECT
public slots:
void doWork() {
qDebug() << "Worker started";
QThread::sleep(2);
qDebug() << "Worker finished";
}
};
int main(int argc, char *argv[]) {
QCoreApplication app(argc, argv);
QThread thread;
Worker worker;
worker.moveToThread(&thread); // 将 worker 移动到新线程
QObject::connect(&thread, &QThread::started, &worker, &Worker::doWork);
thread.start(); // 启动线程
return app.exec();
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# 2.4 多线程编程
QtConcurrent 提供了高级 API,用于简化多线程编程,如并行计算和异步任务。
# 2.4.1 并行计算
使用 QtConcurrent::run() 在另一个线程中执行函数。
#include <QtConcurrent>
#include <QDebug>
void myFunction() {
qDebug() << "Function running in thread";
QThread::sleep(2);
}
int main(int argc, char *argv[]) {
QCoreApplication app(argc, argv);
QFuture<void> future = QtConcurrent::run(myFunction);
future.waitForFinished(); // 等待任务完成
return app.exec();
}
2
3
4
5
6
7
8
9
10
11
12
13
14
# 2.4.2 并行映射
使用 QtConcurrent::map() 对容器中的元素并行处理。
#include <QtConcurrent>
#include <QList>
#include <QDebug>
void square(int &value) {
value *= value;
}
int main(int argc, char *argv[]) {
QCoreApplication app(argc, argv);
QList<int> list = {1, 2, 3, 4, 5};
QtConcurrent::map(list, square); // 对列表中的每个元素平方
qDebug() << list; // 输出: (1, 4, 9, 16, 25)
return app.exec();
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 2.5 线程同步
Qt 提供了多种同步原语(Synchronization Primitives),用于管理多线程之间的并发访问和协调。这些同步原语包括互斥锁、读写锁、信号量、条件变量等。
QMutex:用于互斥访问共享资源。QReadWriteLock:支持多读单写的锁。QSemaphore:控制对共享资源的访问数量。QWaitCondition:用于线程间的条件等待和唤醒。
# 2.5.1 互斥锁QMutex
QMutex 用于保护共享资源,防止多个线程同时访问。基本用法
#include <QMutex>
#include <QThread>
#include <QDebug>
QMutex mutex;
int counter = 0;
class MyThread : public QThread {
protected:
void run() override {
for (int i = 0; i < 1000; ++i) {
mutex.lock(); // 加锁
++counter;
mutex.unlock(); // 解锁
}
}
};
int main(int argc, char *argv[]) {
QCoreApplication app(argc, argv);
MyThread thread1, thread2;
thread1.start();
thread2.start();
thread1.wait();
thread2.wait();
qDebug() << "Counter:" << counter; // 输出: 2000
return app.exec();
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
QMutexLocker,QMutexLocker 是一个 RAII(资源获取即初始化)类,用于自动管理 QMutex 的加锁和解锁。
QMutex mutex;
int counter = 0;
class MyThread : public QThread {
protected:
void run() override {
for (int i = 0; i < 1000; ++i) {
QMutexLocker locker(&mutex); // 自动加锁和解锁
++counter;
}
}
};
2
3
4
5
6
7
8
9
10
11
12
# 2.5.2 QReadWriteLock
QReadWriteLock 允许多个线程同时读取共享资源,但写操作是独占的。基本用法:
#include <QReadWriteLock>
#include <QThread>
#include <QDebug>
QReadWriteLock rwLock;
int data = 0;
class ReaderThread : public QThread {
protected:
void run() override {
rwLock.lockForRead(); // 加读锁
qDebug() << "Read data:" << data;
rwLock.unlock(); // 解读锁
}
};
class WriterThread : public QThread {
protected:
void run() override {
rwLock.lockForWrite(); // 加写锁
++data;
qDebug() << "Write data:" << data;
rwLock.unlock(); // 解写锁
}
};
int main(int argc, char *argv[]) {
QCoreApplication app(argc, argv);
ReaderThread reader;
WriterThread writer;
reader.start();
writer.start();
reader.wait();
writer.wait();
return app.exec();
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
QReadLocker 和 QWriteLocker,类似于 QMutexLocker,QReadLocker 和 QWriteLocker 是 RAII 类,用于自动管理 QReadWriteLock 的加锁和解锁。
QReadWriteLock rwLock;
int data = 0;
class ReaderThread : public QThread {
protected:
void run() override {
QReadLocker locker(&rwLock); // 自动加读锁
qDebug() << "Read data:" << data;
}
};
class WriterThread : public QThread {
protected:
void run() override {
QWriteLocker locker(&rwLock); // 自动加写锁
++data;
qDebug() << "Write data:" << data;
}
};
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# 2.5.3 QSemaphore
QSemaphore 用于控制对共享资源的访问数量。基本用法
#include <QSemaphore>
#include <QThread>
#include <QDebug>
QSemaphore semaphore(1); // 初始值为 1
class WorkerThread : public QThread {
protected:
void run() override {
semaphore.acquire(); // 获取信号量
qDebug() << "Working...";
QThread::sleep(2);
semaphore.release(); // 释放信号量
}
};
int main(int argc, char *argv[]) {
QCoreApplication app(argc, argv);
WorkerThread thread1, thread2;
thread1.start();
thread2.start();
thread1.wait();
thread2.wait();
return app.exec();
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
# 2.5.4 QWaitCondition
QWaitCondition 用于线程间的条件等待和唤醒。基本用法
#include <QWaitCondition>
#include <QMutex>
#include <QThread>
#include <QDebug>
QMutex mutex;
QWaitCondition condition;
bool ready = false;
class Producer : public QThread {
protected:
void run() override {
QThread::sleep(2);
mutex.lock();
ready = true;
condition.wakeAll(); // 唤醒等待的线程
mutex.unlock();
}
};
class Consumer : public QThread {
protected:
void run() override {
mutex.lock();
while (!ready) {
condition.wait(&mutex); // 等待条件满足
}
mutex.unlock();
qDebug() << "Data is ready!";
}
};
int main(int argc, char *argv[]) {
QCoreApplication app(argc, argv);
Producer producer;
Consumer consumer;
producer.start();
consumer.start();
producer.wait();
consumer.wait();
return app.exec();
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44