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);

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

相关推荐
程序猿000001号2 分钟前
使用Python的Seaborn库进行数据可视化
开发语言·python·信息可视化
ཌ斌赋ད5 分钟前
FFTW基本概念与安装使用
c++
一个不正经的林Sir7 分钟前
C#WPF基础介绍/第一个WPF程序
开发语言·c#·wpf
API快乐传递者11 分钟前
Python爬虫获取淘宝详情接口详细解析
开发语言·爬虫·python
公众号Codewar原创作者13 分钟前
R数据分析:工具变量回归的做法和解释,实例解析
开发语言·人工智能·python
赵钰老师16 分钟前
基于R语言APSIM模型应用及批量模拟(精细农业、水肥管理、气候变化、粮食安全、土壤碳周转、环境影响、农业可持续性、农业生态等)
开发语言·数据分析·r语言
lly20240633 分钟前
Highcharts 饼图:数据可视化利器
开发语言
薄荷故人_38 分钟前
从零开始的C++之旅——红黑树封装map_set
c++
lw向北.39 分钟前
Qt For Android之环境搭建(Qt 5.12.11 Qt下载SDK的处理方案)
android·开发语言·qt
IT女孩儿1 小时前
JavaScript--WebAPI查缺补漏(二)
开发语言·前端·javascript·html·ecmascript