一、QThread 的基本概念
QThread 是 Qt 框架中用于多线程编程的类。它允许我们在应用程序中创建和管理线程,从而在后台执行耗时操作,避免阻塞主线程(通常是 GUI 线程),保持用户界面的响应性。
线程与主线程:
- 主线程通常负责处理用户界面和事件循环。
- 子线程用于执行耗时操作,如文件 I/O、网络请求、复杂计算等。
QThread 的作用:
- QThread 提供了一个平台无关的方式来管理线程。
- 它封装了底层操作系统的线程 API,使得线程的创建、启动、停止和管理更加方便。
QThread 的工作方式:
- QThread 本身并不是线程,而是一个线程管理类。
- 可以通过继承 QThread 并重写 run() 方法来定义线程的执行逻辑。
- 或者可以将 QObject 移动到 QThread 中,利用信号和槽机制来执行任务。
二、QThread中的常用成员函数
1.QThread::exit
用于结束线程的事件循环并指定一个返回码。这个函数通常用于控制线程的退出行为,尤其是在使用事件循环的线程中。
函数原型:
void QThread::exit(int returnCode = 0)
功能:
结束线程的事件循环,并设置线程的返回码。调用此函数后,线程的事件循环会退出,线程的执行会从 QThread::exec() 返回。
参数:
returnCode:线程的返回码,默认为 0。这个值可以通过 QThread::exec() 的返回值获取。
使用场景:
当你希望线程在某个条件下退出事件循环时,可以调用此函数。通常与QThread::exec() 配合使用。
以下是一个简单的示例,展示如何使用 QThread::exit() 来结束线程的事件循环。
#include <QThread>
#include <QDebug>
#include <QTimer>
class WorkerThread : public QThread
{
Q_OBJECT
protected:
void run() override {
qDebug() << "Thread started";
// 启动事件循环
int returnCode = exec();
qDebug() << "Thread exited with return code:" << returnCode;
}
public slots:
void stopThread() {
qDebug() << "Stopping thread...";
exit(42); // 结束事件循环,并设置返回码为 42
}
};
int main(int argc, char *argv[])
{
QCoreApplication app(argc, argv);
WorkerThread thread;
thread.start(); // 启动线程
// 使用 QTimer 在 2 秒后停止线程
QTimer::singleShot(2000, &thread, &WorkerThread::stopThread);
qDebug() << "Main thread: worker thread has finished.";
return 0;
}
输出结果:

注意事项:
- 事件循环的必要性:exit() 函数仅对调用 exec() 启动事件循环的线程有效。如果线程没有事件循环,调用 exit() 不会有任何效果。
- 线程安全:exit() 是线程安全的,可以从任何线程调用。
- 返回码的作用:返回码可以用于传递线程的退出状态。例如,0 通常表示成功,非零值表示错误或特定状态。
- 与 quit() 的区别:exit() 和 quit() 的功能类似,但 exit() 可以指定返回码,而 quit() 的返回码固定为 0。
2.QThread::isFinished()
函数原型:
bool QThread::isFinished() const
功能:
返回线程是否已经结束。如果线程已经完成执行,则返回 true;否则返回 false。
参数:
true:线程已经结束。false:线程仍在运行。
使用场景:
在需要等待线程完成时,可以使用此函数检查线程状态。在需要根据线程状态执行特定操作时,可以使用此函数进行判断。
以下是一个简单的示例,展示如何使用 isFinished() 检查线程是否结束。
#include <QThread>
#include <QDebug>
#include <QTimer>
class WorkerThread : public QThread
{
Q_OBJECT
protected:
void run() override {
qDebug() << "Thread started";
// 模拟耗时操作
sleep(3);
qDebug() << "Thread finished";
}
};
int main(int argc, char *argv[])
{
QCoreApplication app(argc, argv);
WorkerThread thread;
thread.start(); // 启动线程
// 检查线程是否结束
while (!thread.isFinished()) {
qDebug() << "Thread is still running...";
QThread::sleep(1); // 主线程等待 1 秒
}
qDebug() << "Main thread: worker thread has finished.";
return 0;
}
输出结果:

注意事项:·
- 线程状态检查:isFinished() 是一个非阻塞函数,可以随时调用以检查线程状态。
- 与 wait() 的区别:isFinished() 仅检查线程状态,不会阻塞当前线程。wait() 会阻塞当前线程,直到目标线程结束。
- 线程安全:isFinished() 是线程安全的,可以从任何线程调用。
- 线程结束的条件:线程结束的条件是 run() 方法执行完毕或调用了 QThread::exit() 或 QThread::quit()。
3.QThread::isInterruptionRequested()
用于检查当前线程是否被请求中断。这个函数通常用于实现线程的优雅退出机制,允许线程在执行任务时定期检查中断请求,并在适当的时候安全地终止。
函数原型:
bool QThread::isInterruptionRequested() const
功能:
返回线程是否被请求中断。如果线程的中断标志被设置(通过 QThread::requestInterruption()),则返回 true;否则返回 false。
返回值:
true:线程的中断标志被设置,表示线程被请求中断。false:线程的中断标志未被设置,表示线程可以继续运行。
使用场景:
在线程的 run() 方法中定期检查中断请求,以实现线程的优雅退出。在需要长时间运行的任务中,提供一种机制来安全地终止线程。
以下是一个简单的示例,展示如何使用 isInterruptionRequested() 实现线程的优雅退出。
#include <QThread>
#include <QDebug>
#include <QTimer>
class WorkerThread : public QThread
{
Q_OBJECT
protected:
void run() override {
qDebug() << "Thread started";
for (int i = 0; i < 10; ++i) {
// 检查中断请求
if (isInterruptionRequested()) {
qDebug() << "Thread interrupted, exiting...";
return; // 退出线程
}
qDebug() << "Working on task" << i;
sleep(1); // 模拟耗时操作
}
qDebug() << "Thread finished";
}
};
int main(int argc, char *argv[])
{
QCoreApplication app(argc, argv);
WorkerThread thread;
thread.start(); // 启动线程
// 使用 QTimer 在 3 秒后请求中断线程
QTimer::singleShot(3000, [&thread]() {
qDebug() << "Requesting thread interruption...";
thread.requestInterruption(); // 请求中断线程
});
qDebug() << "Main thread: worker thread has finished.";
return 0;
}
输出结果:

注意事项:
- 中断请求的检查:isInterruptionRequested() 是一个非阻塞函数,可以在线程的任何地方调用。建议在耗时操作或循环中定期检查中断请求,以确保线程能够及时响应中断。
- 中断请求的设置:中断请求通过 QThread::requestInterruption() 设置。中断请求是一个标志,不会强制终止线程,线程需要主动检查并退出。
- 线程安全:isInterruptionRequested() 和 requestInterruption() 都是线程安全的,可以从任何线程调用。

最低0.47元/天 解锁文章
1万+

被折叠的 条评论
为什么被折叠?



