Qt之线程的使用

多线程编程是一种常见的技术,它可以提高程序的性能和响应性。Qt 是一个广泛使用的跨平台 C++ 图形用户界面(GUI)库,它提供了方便的线程支持。在本文中,我们将探讨 Qt 线程的使用,并通过示例来展示如何在 Qt 应用程序中创建和管理线程。

首先,让我们了解一下线程的基本概念。线程是程序执行的独立路径,每个线程可以同时执行不同的任务。通过创建多个线程,我们可以并行处理多个任务,从而提高程序的执行效率。

在 Qt 中,可以使用QThread类来创建和管理线程。以下是一个简单的示例,展示了如何在 Qt 中使用线程:

复制代码
#include <QThread>
#include <QDebug>

// 要在线程中执行的任务函数
void taskFunction() {
    qDebug() << "Task running in thread";
}

int main() {
    // 创建一个新线程
    QThread thread;
    // 在新线程中执行任务函数
    QObject::connect(&thread, &QThread::started, []() {
        taskFunction();
    });
    
    thread.start();
    
    // 等待线程执行完成
    thread.waitForFinished();
    return 0;
}

在上述示例中,我们创建了一个QThread对象thread。然后,我们使用connect函数将QThread::started信号与一个匿名函数连接起来,该函数会在线程启动后执行taskFunction。

接下来,我们使用start函数启动线程,线程将开始执行taskFunction。

最后,我们使用waitForFinished函数等待线程执行完成。

请注意,在实际应用中,你可能需要在线程中处理更复杂的任务,并在适当的时候进行线程间的通信和同步。此外,还可以使用QMutex、QSemaphore等同步对象来保护共享数据的访问。

另外,线程的创建和管理也需要谨慎处理。过度创建线程可能会导致系统资源的消耗和性能下降。在实际应用中,需要根据任务的特性和需求来合理规划线程的数量和使用方式。

除了手动创建线程,Qt 还提供了一些更高级的线程管理工具,例如QThreadPool和QtConcurrent。QThreadPool可以方便地管理一组线程,并将任务分配到空闲的线程中执行。QtConcurrent提供了一些简化的并行计算接口,使得编写多线程代码更加简单和高效。

使用 QThreadPool::globalInstance() 线程池操作

QThreadPool用于管理和回收单个QThread对象,以帮助减少使用线程的程序中的线程创建成本。每个Qt应用程序都有一个全局QThreadPool对象,可以通过调用globalInstance()进行访问。

复制代码
class Task : public QRunnable
{
    void run() override
    {
        // 费时操作
        qDebug() << "thread run at:" << QThread::currentThread();
    }
};
 
auto *task = new Task();
QThreadPool::globalInstance()->start(task);

注意事项:

  • 默认情况下, 用户在调用 QThreadPool::globalInstance()->start(task); 之后不需要再关心 task 对象的释放问题,因为 QThreadPool 会自动删除 task。当然也可以通过 QRunnable :: setAutoDelete(bool) 调整策略。

  • 在一定时间内未使用的线程将过期。默认的到期超时为30000毫秒(30秒)。可以使用setExpiryTimeout()进行调整。当设置到期超时为负值时将禁用到期机制。

  • maxThreadCount()方法可以查询最大线程数,也可以使用setMaxThreadCount()进行调整。默认的maxThreadCount()是QThread::idealThreadCount()。

  • QThreadPool 是一个用于管理线程的低级类,高级玩法请参照 QtConcurrent 模块。

QtConcurrent模块。(高级玩法)

QtConcurrent模块扩展了Qt Core模块中提供的基本线程支持,并简化了可在所有可用CPU内核上并行执行的代码的开发。 The QtConcurrent namespace provides high-level APIs that make it possible to write multi-threaded programs without using low-level threading primitives such as mutexes, read-write locks, wait conditions, or semaphores. Programs written with QtConcurrent automatically adjust the number of threads used according to the number of processor cores available. This means that applications written today will continue to scale when deployed on multi-core systems in the future.

此模块简化了用户操作,强烈推荐使用。

下面是一个简单的示例。

复制代码
// 方法参数为 Function 
// 可以处理返回值
QFuture<int> res = QtConcurrent::run([](){ 
    // 费时操作
    return 0;
});
 
// 可以等待处理完成
// 1.阻塞执行 不阻塞事件循环
// while(!res.isFinished()) {
    // wait
    // QApplication::processEvents(QEventLoop::AllEvents, 200);
// }
// 2. 阻塞等待
res.waitForFinished();
 
// 处理返回值
int result = res.result();

注意事项:

  • 需要引入 Qt Concurrent模块。

  • 可以使用 QFutureWatcher 监视 QFuture。以下是一个官方示例:

    // Instantiate the objects and connect to the finished signal.
    MyClass myObject;
    QFutureWatcher watcher;
    connect(&watcher, QFutureWatcher::finished, &myObject, &MyClass::handleFinished);

    // Start the computation.
    QFuture future = QtConcurrent::run(...);
    watcher.setFuture(future);

码字不易,欢迎点赞支持!

相关推荐
星夜离尘5624 分钟前
MATLAB 工程实验:不等间隔流量积分,先把缺口与覆盖率说清楚
开发语言·matlab·时间戳·数据质量·数值积分
Ai-_Man1 小时前
Meta Muse还是不可以导出左侧所有对话,只能点进去单条内容导出,方法不对吗?
开发语言·人工智能·ai·小程序·c#·1024程序员节
梓豪csd1 小时前
消息订阅中心:谁该收到哪条通知
java·开发语言·人工智能·低代码·自动化·1024程序员节
会编程的小孩1 小时前
C++ qt的安装
c++
学逆向的1 小时前
C 枚举变量
c语言·开发语言·网络安全
Sakura_j_h_2 小时前
Python 在定时任务里输出 emoji,UnicodeEncodeError 从哪来
开发语言·字符编码·windows·python·定时任务
小成202303202657 小时前
C++~07补充
开发语言·c++
hold?fish:palm7 小时前
40 二叉树的直径
c++·leetcode
LaoWaiHang7 小时前
关于Qt中鼠标左键事件被子控件截留的处理
qt