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函数等待线程执行完成。

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

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

除了手动创建线程,Qt 还提供了一些更高级的线程管理工具,例如QThreadPoolQtConcurrentQThreadPool可以方便地管理一组线程,并将任务分配到空闲的线程中执行。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<int> watcher;
connect(&watcher, QFutureWatcher<int>::finished, &myObject, &MyClass::handleFinished);
 
// Start the computation.
QFuture<int> future = QtConcurrent::run(...);
watcher.setFuture(future);

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

  • 14
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

编程与实战

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值