qt 线程编程

简介: qt 线程编程

本篇文章来介绍一下老生常谈的问题 那就是qt线程编程

1.QThread类

QThread 是 Qt 中处理多线程的传统方式。每个 QThread 对象代表一个线程。要在线程中运行的代码通常放在 QObject 派生的类中,并重写 run() 方法。然后,可以将这个对象移到新线程中。

代码示例:

class Worker : public QObject  
{  
    Q_OBJECT  
public slots:  
    void doWork() {  
        // 这里是线程要执行的代码  
    }  
};  
  
// 在某个地方创建线程和工作对象  
QThread *thread = new QThread;  
Worker *worker = new Worker;  
worker->moveToThread(thread);  
  
// 连接信号和槽  
connect(thread, &QThread::started, worker, &Worker::doWork);  
connect(worker, &Worker::workFinished, thread, &QThread::quit);  
connect(worker, &Worker::workFinished, worker, &Worker::deleteLater);  
connect(thread, &QThread::finished, thread, &QThread::deleteLater);  
  
// 开始线程  
thread->start();

2.使用 Qt 并发库

Qt 5 引入了 Qt Concurrent 模块,它提供了一种更简单的方式来编写并发代码,而无需直接处理线程。Qt Concurrent 提供了一组函数,如 QtConcurrent::run(),它可以在一个新的线程中执行任何可调用的对象。

示例代码:

#include <QtConcurrent/QtConcurrentRun>  
  
void someFunction() {  
    // 这里是线程要执行的代码  
}  
  
// 在某个地方调用函数  
QtConcurrent::run(someFunction);

注意事项:

  • 线程安全:在多线程环境中,需要特别注意线程安全问题,如访问共享资源时的竞态条件。
  • 信号和槽:Qt 的信号和槽机制是线程安全的,可以在不同线程之间安全地发送信号和槽。
  • 资源访问:避免在多个线程中同时访问 GUI 组件,因为这可能导致不可预测的行为。如果需要更新 GUI,应该使用信号和槽机制将更新请求发送到主线程。
  • 线程退出:确保线程在完成任务后正确退出,并释放所有资源。

 

3.qt锁的应用

Qt 锁是 Qt 框架中提供的一种机制,用于保护共享资源免受多个线程的同时访问,以防止数据竞争和不一致。Qt 提供了几种不同类型的锁,以满足不同的需求。

  1. QMutex(互斥锁)这是最基本的锁类型,用于确保同一时间只有一个线程可以访问某个资源。如果一个线程已经锁定了互斥锁,任何其他尝试锁定该互斥锁的线程都将被阻塞,直到原始线程释放锁。
  2. QReadWriteLock(读写锁)这种锁允许多个线程同时读取共享资源,但在写入资源时只允许一个线程访问。如果一个线程已经锁定了写锁,其他所有尝试读取或写入资源的线程都将被阻塞。如果一个线程已经锁定了读锁,其他线程仍然可以锁定读锁以读取资源,但不能锁定写锁。Qt 的 QReadWriteLock 默认使用写优先策略,这意味着当写锁可用时,它会被优先分配给请求写锁的线程。
  3. QSemaphore(信号量)信号量是一个计数器,用于控制对共享资源的访问。线程可以请求(即“获取”)一定数量的信号量,如果信号量可用,则请求成功,线程可以继续执行。如果信号量不可用,线程将被阻塞,直到有足够的信号量可用。信号量常用于实现生产者-消费者问题、资源池等场景。

qt QMutex锁代码实例:

#include <QMutex>  
#include <QThread>  
#include <QDebug>  
  
class SharedResource {  
public:  
    SharedResource() : value(0) {}  
  
    // 锁定互斥锁以访问共享数据  
    void setValue(int newValue) {  
        QMutexLocker locker(&mutex); // 使用 QMutexLocker 自动管理锁的获取和释放  
        value = newValue;  
    }  
  
    int getValue() {  
        QMutexLocker locker(&mutex); // 使用 QMutexLocker 自动管理锁的获取和释放  
        return value;  
    }  
  
private:  
    int value;  
    QMutex mutex; // 互斥锁用于保护共享数据  
};
class WorkerThread : public QThread {  
    Q_OBJECT  
  
public:  
    WorkerThread(SharedResource *resource, QObject *parent = nullptr)  
        : QThread(parent), resource(resource) {}  
  
protected:  
    void run() override {  
        // 模拟线程工作,比如增加共享资源的值  
        for (int i = 0; i < 10; ++i) {  
            resource->setValue(resource->getValue() + 1);  
            qDebug() << "Thread" << currentThreadId() << "value:" << resource->getValue();  
            QThread::sleep(1); // 暂停一秒以模拟工作  
        }  
    }  
  
private:  
    SharedResource *resource;  
};
int main(int argc, char *argv[]) {  
    QCoreApplication app(argc, argv);  
  
    SharedResource resource;  
  
    // 创建并启动工作线程  
    WorkerThread *thread1 = new WorkerThread(&resource);  
    WorkerThread *thread2 = new WorkerThread(&resource);  
  
    thread1->start();  
    thread2->start();  
  
    // 等待线程完成  
    thread1->wait();  
    thread2->wait();  
  
    qDebug() << "Final value:" << resource.getValue();  
  
    return app.exec();  
}

在这里祝大家新的一年财源广进

好了 本篇文章就到这里结束了 在这里我向大家推荐一个高质量课程:

https://xxetb.xetslk.com/s/2PjJ3T

相关文章
|
9月前
|
Java API 微服务
为什么虚拟线程将改变Java并发编程?
为什么虚拟线程将改变Java并发编程?
419 83
|
6月前
|
Java
如何在Java中进行多线程编程
Java多线程编程常用方式包括:继承Thread类、实现Runnable接口、Callable接口(可返回结果)及使用线程池。推荐线程池以提升性能,避免频繁创建线程。结合同步与通信机制,可有效管理并发任务。
273 6
|
11月前
|
机器学习/深度学习 消息中间件 存储
【高薪程序员必看】万字长文拆解Java并发编程!(9-2):并发工具-线程池
🌟 ​大家好,我是摘星!​ 🌟今天为大家带来的是并发编程中的强力并发工具-线程池,废话不多说让我们直接开始。
407 0
|
7月前
|
算法 Java
Java多线程编程:实现线程间数据共享机制
以上就是Java中几种主要处理多线程序列化资源以及协调各自独立运行但需相互配合以完成任务threads 的技术手段与策略。正确应用上述技术将大大增强你程序稳定性与效率同时也降低bug出现率因此深刻理解每项技术背后理论至关重要.
497 16
|
6月前
|
Java 调度 数据库
Python threading模块:多线程编程的实战指南
本文深入讲解Python多线程编程,涵盖threading模块的核心用法:线程创建、生命周期、同步机制(锁、信号量、条件变量)、线程通信(队列)、守护线程与线程池应用。结合实战案例,如多线程下载器,帮助开发者提升程序并发性能,适用于I/O密集型任务处理。
672 0
|
Linux
Linux编程: 在业务线程中注册和处理Linux信号
通过本文,您可以了解如何在业务线程中注册和处理Linux信号。正确处理信号可以提高程序的健壮性和稳定性。希望这些内容能帮助您更好地理解和应用Linux信号处理机制。
278 26
|
Linux
Linux编程: 在业务线程中注册和处理Linux信号
本文详细介绍了如何在Linux中通过在业务线程中注册和处理信号。我们讨论了信号的基本概念,并通过完整的代码示例展示了在业务线程中注册和处理信号的方法。通过正确地使用信号处理机制,可以提高程序的健壮性和响应能力。希望本文能帮助您更好地理解和应用Linux信号处理,提高开发效率和代码质量。
301 17
|
存储 安全 Java
Java多线程编程秘籍:各种方案一网打尽,不要错过!
Java 中实现多线程的方式主要有四种:继承 Thread 类、实现 Runnable 接口、实现 Callable 接口和使用线程池。每种方式各有优缺点,适用于不同的场景。继承 Thread 类最简单,实现 Runnable 接口更灵活,Callable 接口支持返回结果,线程池则便于管理和复用线程。实际应用中可根据需求选择合适的方式。此外,还介绍了多线程相关的常见面试问题及答案,涵盖线程概念、线程安全、线程池等知识点。
868 2
|
安全 算法 Java
Java多线程编程中的陷阱与最佳实践####
本文探讨了Java多线程编程中常见的陷阱,并介绍了如何通过最佳实践来避免这些问题。我们将从基础概念入手,逐步深入到具体的代码示例,帮助开发者更好地理解和应用多线程技术。无论是初学者还是有经验的开发者,都能从中获得有价值的见解和建议。 ####
|
安全 Java API
【JavaEE】多线程编程引入——认识Thread类
Thread类,Thread中的run方法,在编程中怎么调度多线程

热门文章

最新文章

推荐镜像

更多
  • qt
  • 下一篇
    开通oss服务