QT-------------多线程

news2025/2/26 8:15:56

实现思路

  1. QThread 类简介
    • QThread 是 Qt 中用于多线程编程的基础类。可以通过继承 QThread 并重写 run() 方法来创建自定义的线程逻辑。
    • 新线程的执行从 run() 开始,调用 start() 方法启动线程。
  2. 掷骰子的多线程应用程序
    • 创建一个 DiceThread 类继承自 QThread,在 run() 方法中模拟掷骰子操作,并通过信号将结果发送出去。
  3. 线程同步
    • 线程同步的概念:确保多个线程之间协调操作,避免数据竞争和不一致性。
    • 基于互斥量的线程同步:使用 QMutex 确保在同一时间只有一个线程可以访问共享资源。
    • 基于读写锁的线程同步:使用 QReadWriteLock,允许多个读线程同时访问资源,但写线程独占资源。
    • 基于条件等待的线程同步:使用 QWaitConditionQMutex 结合,允许线程等待某个条件满足。
    • 基于信号量的线程同步:使用 QSemaphore 控制对资源的访问数量。

代码示例

1. QThread 类简介和掷骰子的多线程应用程序
#include <QtWidgets/QApplication>
#include <QtCore/QThread>
#include <QtCore/QRandomGenerator>
#include <QtCore/QDebug>
#include <QtCore/QMutex>
#include <QtCore/QReadWriteLock>
#include <QtCore/QWaitCondition>
#include <QtCore/QSemaphore>


class DiceThread : public QThread {
    Q_OBJECT
signals:
    void resultReady(int result);


protected:
    void run() override {
        while (!isInterruptionRequested()) {
            int diceValue = QRandomGenerator::global()->bounded(1, 7);
            emit resultReady(diceValue);
            msleep(1000);
        }
    }
};


int main(int argc, char *argv[]) {
    QApplication app(argc, argv);


    DiceThread diceThread;
    QObject::connect(&diceThread, &DiceThread::resultReady, [](int result) {
        qDebug() << "Dice result: " << result;
    });


    diceThread.start();


    // 运行一段时间后停止线程
    QThread::sleep(10);
    diceThread.requestInterruption();
    diceThread.wait();


    return app.exec();
}


#include "main.moc"
2. 基于互斥量的线程同步
#include <QtWidgets/QApplication>
#include <QtCore/QThread>
#include <QtCore/QRandomGenerator>
#include <QtCore/QDebug>
#include <QtCore/QMutex>


class SharedData {
public:
    int value = 0;
    QMutex mutex;
};


class IncrementThread : public QThread {
public:
    IncrementThread(SharedData *data) : data(data) {}


protected:
    void run() override {
        for (int i = 0; i < 1000; ++i) {
            data->mutex.lock();
            ++data->value;
            data->mutex.unlock();
            msleep(1);
        }
    }


private:
    SharedData *data;
};


int main(int argc, char *argv[]) {
    QApplication app(argc, argv);


    SharedData sharedData;


    IncrementThread thread1(&sharedData);
    IncrementThread thread2(&sharedData);


    thread1.start();
    thread2.start();


    thread1.wait();
    thread2.wait();


    qDebug() << "Final value: " << sharedData.value;


    return app.exec();
}


#include "main.moc"
3. 基于读写锁的线程同步
#include <QtWidgets/QApplication>
#include <QtCore/QThread>
#include <QtCore/QRandomGenerator>
#include <QtCore/QDebug>
#include <QtCore/QReadWriteLock>


class SharedData {
public:
    int value = 0;
    QReadWriteLock lock;
};


class ReadThread : public QThread {
public:
    ReadThread(SharedData *data) : data(data) {}


protected:
    void run() override {
        for (int i = 0; i < 1000; ++i) {
            data->lock.lockForRead();
            qDebug() << "Read value: " << data->value;
            data->lock.unlock();
            msleep(1);
        }
    }


private:
    SharedData *data;
};


class WriteThread : public QThread {
public:
    WriteThread(SharedData *data) : data(data) {}


protected:
    void run() override {
        for (int i = 0; i < 100; ++i) {
            data->lock.lockForWrite();
            ++data->value;
            data->lock.unlock();
            msleep(10);
        }
    }


private:
    SharedData *data;
};


int main(int argc, char *argv[]) {
    QApplication app(argc, argv);


    SharedData sharedData;


    ReadThread reader1(&sharedData);
    ReadThread reader2(&sharedData);
    WriteThread writer(&sharedData);


    reader1.start();
    reader2.start();
    writer.start();


    reader1.wait();
    reader2.wait();
    writer.wait();


    qDebug() << "Final value: " << sharedData.value;


    return app.exec();
}


#include "main.moc"

在这里插入图片描述

4. 基于条件等待的线程同步
#include <QtWidgets/QApplication>
#include <QtCore/QThread>
#include <QtCore/QRandomGenerator>
#include <QtCore/QDebug>
#include <QtCore/QMutex>
#include <QtCore/QWaitCondition>


class SharedData {
public:
    int value = 0;
    QMutex mutex;
    QWaitCondition condition;
    bool ready = false;
};


class ProducerThread : public QThread {
public:
    ProducerThread(SharedData *data) : data(data) {}


protected:
    void run() override {
        QRandomGenerator gen;
        for (int i = 0; i < 10; ++i) {
            QThread::msleep(1000);
            data->mutex.lock();
            data->value = gen.bounded(1, 100);
            data->ready = true;
            data->condition.wakeOne();
            data->mutex.unlock();
        }
    }


private:
    SharedData *data;
};


class ConsumerThread : public QThread {
public:
    ConsumerThread(SharedData *data) : data(data) {}


protected:
    void run() override {
        while (true) {
            data->mutex.lock();
            if (!data->ready) {
                data->condition.wait(&data->mutex);
            }
            qDebug() << "Consumed value: " << data->value;
            data->ready = false;
            data->mutex.unlock();
        }
    }


private:
    SharedData *data;
};


int main(int argc, char *argv[]) {
    QApplication app(argc, argv);


    SharedData sharedData;


    ProducerThread producer(&sharedData);
    ConsumerThread consumer(&sharedData);


    consumer.start();
    producer.start();


    return app.exec();
}


#include "main.moc"
5. 基于信号量的线程同步
#include <QtWidgets/QApplication>
#include <QtCore/QThread>
#include <QtCore/QRandomGenerator>
#include <QtCore/QDebug>
#include <QtCore/QSemaphore>


class SharedResource {
public:
    QSemaphore semaphore;


    void useResource() {
        semaphore.acquire();
        qDebug() << "Using resource...";
        QThread::msleep(100);
        semaphore.release();
    }
};


class UserThread : public QThread {
public:
    UserThread(SharedResource *resource) : resource(resource) {}


protected:
    void run() override {
        for (int i = 0; i < 10; ++i) {
            resource->useResource();
        }
    }


private:
    SharedResource *resource;
};


int main(int argc, char *argv[]) {
    QApplication app(argc, argv);


    SharedResource resource;
    resource.semaphore.release(3);


    UserThread thread1(&resource);
    UserThread thread2(&resource);
    UserThread thread3(&resource);


    thread1.start();
    thread2.start();
    thread3.start();


    thread1.wait();
    thread2.wait();
    thread3.wait();


    return app.exec();
}


#include "main.moc"

代码解释

1. QThread 类简介和掷骰子的多线程应用程序
  • DiceThread 类
    • 继承 QThread 并在 run() 中模拟掷骰子操作,使用 QRandomGenerator 生成 1 到 6 的随机数。
    • 通过 resultReady 信号将结果发送出去,在主线程中连接该信号并打印结果。
2. 基于互斥量的线程同步
  • SharedData 类
    • 包含一个 value 变量和 QMutex
  • IncrementThread 类
    • 每次循环对 value 加 1 前先加锁,加 1 后解锁,确保同一时间只有一个线程修改 value
3. 基于读写锁的线程同步
  • SharedData 类
    • 包含一个 value 变量和 QReadWriteLock
  • ReadThread 类
    • 读线程使用 lockForRead() 锁定,读取 value 后解锁。
  • WriteThread 类
    • 写线程使用 lockForWrite() 锁定,修改 value 后解锁,写线程独占资源,读线程可同时读。
4. 基于条件等待的线程同步
  • SharedData 类
    • 包含 valueQMutexQWaitConditionready 标志。
  • ProducerThread 类
    • 生产者线程生成数据,使用 wakeOne() 唤醒等待的消费者。
  • ConsumerThread 类
    • 消费者线程等待 ready 标志,使用 wait() 等待,一旦有数据可用,打印并重置 ready
5. 基于信号量的线程同步
  • SharedResource 类
    • 包含 QSemaphore,初始释放 3 个资源。
  • UserThread 类
    • 每次使用资源前先 acquire() 资源,使用后 release() 资源,确保最多 3 个线程同时使用资源。

使用说明

  • 对于每个示例,将代码保存为 main.cpp 文件。
  • 确保 .pro 文件包含 QT += core widgets 以及 CONFIG += c++11
  • 编译并运行程序,观察不同线程同步机制的效果。

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2270422.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

VBA批量插入图片到PPT,一页一图

Sub InsertPicturesIntoSlides()Dim pptApp As ObjectDim pptPres As ObjectDim pptSlide As ObjectDim strFolderPath As StringDim strFileName As StringDim i As Integer 设置图片文件夹路径strFolderPath "C:\您的图片文件夹路径\" 请替换为您的图片文件夹路径…

当知识图谱遇上文本智能处理,会擦出怎样的火花?

目前以理解人类语言为入口的认知智能成为了人工智能发展的突破点&#xff0c;而知识图谱则是迈向认知智能的关键要素。达观数据在2018AIIA人工智能开发者大会承办的语言认知智能与知识图谱公开课上&#xff0c;三位来自企业和学术领域的专家分别从不同角度讲述的知识图谱的应用…

数据挖掘——回归算法

数据挖掘——回归算法 回归算法线性回归最小二乘法优化求解——梯度下降法逻辑回归逻辑回归函数逻辑回归参数估计逻辑回归正则化 决策树回归小结 回归算法 回归分析 如果把其中的一些因素&#xff08;房屋面积&#xff09;作为自变量&#xff0c;而另一些随自变量的变化而变化…

Ubuntu 24.04 LTS 解决网络连接问题

1. 问题描述 现象&#xff1a;ens33 网络接口无法获取 IPv4 地址&#xff0c;导致网络不可用。初步排查&#xff1a; 运行 ip a&#xff0c;发现 ens33 接口没有分配 IPv4 地址。运行 ping www.baidu.com&#xff0c;提示“网络不可达”。查看 NetworkManager 日志&#xff0c…

spring-boot启动源码分析(二)之SpringApplicationRunListener

在上一篇《spring-boot启动源码分析&#xff08;一&#xff09;之SpringApplication实例构造》后&#xff0c;继续看了一个月的Spring boot启动源码&#xff0c;初步把流程看完了&#xff0c;接下来会不断输出总结&#xff0c;以巩固这段时间的学习。同时也希望能帮到同样感兴趣…

基于N-HiTS神经层次插值模型的时间序列预测——cross validation交叉验证与ray tune超参数优化

论文链接&#xff1a;https://arxiv.org/pdf/2201.12886v3 N-HiTS: Neural Hierarchical Interpolation for TimeSeries Forecasting \begin{aligned} &\text{\large \color{#CDA59E}N-HiTS: Neural Hierarchical Interpolation for TimeSeries Forecasting}\\ \end{aligne…

Lumos学习王佩丰Excel第二十三讲:Excel图表与PPT

一、双坐标柱形图的补充知识 1、主次坐标设置 2、主次坐标柱形避让&#xff08;通过增加两个系列&#xff0c;挤压使得两个柱形挨在一起&#xff09; 增加两个系列 将一个系列设置成主坐标轴&#xff0c;另一个设成次坐标轴 调整系列位置 二、饼图美化 1、饼图美化常见设置 …

YK人工智能(三)——万字长文学会torch深度学习

2.1 张量 本节主要内容&#xff1a; 张量的简介PyTorch如何创建张量PyTorch中张量的操作PyTorch中张量的广播机制 2.1.1 简介 几何代数中定义的张量是基于向量和矩阵的推广&#xff0c;比如我们可以将标量视为零阶张量&#xff0c;矢量可以视为一阶张量&#xff0c;矩阵就是…

Java基于SpringBoot的甘肃非物质文化网站的设计与实现,附源码

博主介绍&#xff1a;✌Java老徐、7年大厂程序员经历。全网粉丝12w、csdn博客专家、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精彩专栏推荐订阅&#x1f447;&…

计算机网络:网络层知识点及习题(一)

网课资源&#xff1a; 湖科大教书匠 1、概述 网络层实现主机到主机的传输&#xff0c;主要有分组转发和路由选择两大功能 路由选择处理机得出路由表&#xff0c;路由表再生成转发表&#xff0c;从而实现分组从不同的端口转发 网络层向上层提供的两种服务&#xff1a;面向连接…

ACL的注意事项

ACL只对数据进行抓取和匹配&#xff0c;ACl本身不对数据做拒绝和允许的操作&#xff0c;只有在接口方向上应用后才对数据进行拒绝或允许的操作。 ACl只在packetfilter包过滤时默认动作是允许&#xff0c;这个时候至少需要有一条deny规则&#xff0c;否则全都是允许的规则&…

【Cesium】九、Cesium点击地图获取点击位置的坐标,并在地图上添加图标

文章目录 一、前言二、实现方法三、App.vue 一、前言 查找发现好几种方法可以获取到点击位置的坐标。这里我实现需求就不深究学习了。将几位大佬的方法学习过来稍微整合了一下。 本文参考文章&#xff1a; cesium 4种拾取坐标的方法 【Cesium基础学习】拾取坐标 cesium拾取当…

OpenStack的核心组件、主要特点和使用场景

OpenStack 是一个开源的云计算平台&#xff0c;主要用于构建和管理公共及私有云环境。它由多个模块组成&#xff0c;提供虚拟化资源管理、存储管理、网络配置等功能&#xff0c;旨在为数据中心提供自动化的、灵活的云基础设施服务。OpenStack最初由NASA和Rackspace共同开发&…

51c自动驾驶~合集44

我自己的原文哦~ https://blog.51cto.com/whaosoft/12969097 #Towards Generalist Robot Policies 清华大学&字节 | 迈向通用机器人策略&#xff1a;如何选择VLA&#xff1f; 论文标题&#xff1a;Towards Generalist Robot Policies: What Matters in Building Vision…

17爬虫:关于DrissionPage相关内容的学习01

概述 前面我们已经大致了解了selenium的用法&#xff0c;DerssionPage同selenium一样&#xff0c;也是一个基于Python的网页自动化工具。 DrissionPage既可以实现网页的自动化操作&#xff0c;也能够实现收发数据包&#xff0c;也可以把两者的功能合二为一。 DressionPage的…

SSM-Spring-AOP

目录 1 AOP实现步骤&#xff08;以前打印当前系统的时间为例&#xff09; 2 AOP工作流程 3 AOP核心概念 4 AOP配置管理 4-1 AOP切入点表达式 4-1-1 语法格式 4-1-2 通配符 4-2 AOP通知类型 五种通知类型 AOP通知获取数据 获取参数 获取返回值 获取异常 总结 5 …

【Linux】:线程安全 + 死锁问题

&#x1f4c3;个人主页&#xff1a;island1314 &#x1f525;个人专栏&#xff1a;Linux—登神长阶 ⛺️ 欢迎关注&#xff1a;&#x1f44d;点赞 &#x1f442;&#x1f3fd;留言 &#x1f60d;收藏 &#x1f49e; &#x1f49e; &#x1f49e; 1. 线程安全和重入问题&…

数字电路期末复习

*前言&#xff1a;*写的东西不太全面&#xff0c;更多的是一个复习大纲&#xff0c;让你发现自己有哪些不懂的问题&#xff08;不懂的地方就去翻书或者问AI&#xff09;&#xff0c;如果能够解决提出的所有问题&#xff0c;那么过期末考一定不是问题。 这里写目录标题 数制和码…

python数据分析:使用pandas库读取和编辑Excel表

使用 Pandas&#xff0c;我们可以轻松地读取和写入Excel 文件&#xff0c;之前文章我们介绍了其他多种方法。 使用前确保已经安装pandas和 openpyxl库&#xff08;默认使用该库处理Excel文件&#xff09;。没有安装的可以使用pip命令安装&#xff1a; pip install pandas ope…

“AI人工智能软件开发公司:创新技术,引领未来

大家好&#xff01;今天我们来聊聊一个充满未来感的话题——AI人工智能软件开发公司。这个公司&#xff0c;用大白话说&#xff0c;就是专门研究和开发人工智能软件的地方&#xff0c;它们用最新的技术帮我们解决问题&#xff0c;让生活和工作变得更智能、更便捷。听起来是不是…