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

实现思路

  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.rhkb.cn/news/500597.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

在C语言基础上的C++(深入理解类和对象)

1&#xff1a;构造函数 1&#xff1a;为什么使用构造函数 由于类的封装性&#xff0c;一般来说&#xff0c;数据成员是不能被外界访问的&#xff0c;所以对象的数据成员的初始化工作就给共有函数来完成了。如果定义了构造函数&#xff0c;那么只要对象一建立&#xff0c;就可…

ESP32_H2-ESP32_H2(IDF)学习系列-安装官方组件

1、 在VS Code项目工程中添加IDF组件注册表中的组件十分便捷。您只需按下“CtrlShiftP”快捷键快速进入命令面板&#xff0c;或者通过菜单栏的“查看”选项&#xff0c;选择“命令面板”来打开它。随后&#xff0c;在命令面板中输入“ESP-IDF: Show Component Registry”即可展…

【UE5】UnrealEngine源码构建2:windows构建unreal engine 5.3.2

参考大神知乎的文章:UE5 小白也能看懂的源码编译指南 据说会耗费400G的空间。 代码本身并不大,可能是依赖特别多,毕竟看起来UE啥都能干,核心还是c++的, 【UE5】UnrealEngine源码构建1:tag为5.3.2源码clone 本着好奇+ 学习的态度,想着也许有机会能更为深入的熟悉UE的机制…

[Qt] 常用控件 | QWidget | “表白程序2.0”

目录 一、控件概述 控件体系的发展阶段&#xff1a; 二、QWidget 核心属性 核心属性概览&#xff1a; 1、enabled 2、Geometry 实例 1: 控制按钮的位置 实例 2: 表白 程序 i、Window Frame 的影响 ii、API 设计理念 iii、Geometry 和 FrameGeometry 的区别 &#xf…

laravel部署到云服务器上,除了首页之外,区域页面找不到路由

laravel部署到云服务器上&#xff0c;除了首页之外&#xff0c;区域页面找不到路由&#xff0c;都是报404错误 解决方法&#xff1a; &#xff08;注&#xff1a;本人服务器使用宝塔面板&#xff09; 打开宝塔面板&#xff0c;找到该站点->配置文件 在下方增加如下代码 …

git注意事项

提交代码的备注 feat : 开发 新增功能 fix: 修复 git相关 1. git安装及全局用户设置 Git安装 npm install git -ggit修改用户名邮箱密码 git config --global --replace-all user.name "要修改的用户名" git config --global --replace-all user.email"要修改…

Agent系列:AppAgent v2-屏幕智能Agent(详解版)

引言 简介 方法 Agent 框架 Agent 交互 探索阶段 部署阶段 文档生成 高级功能 实验结果 总结 局限性 未来工作 1. 引言 大语言模型&#xff08;LLM&#xff09;如 ChatGPT 和 GPT-4 显著提升了自然语言处理能力&#xff0c;并且推动了智能体在自主决策中的应用。…

flink cdc oceanbase

接上文&#xff1a;一文说清flink从编码到部署上线 环境&#xff1a;①操作系统&#xff1a;阿里龙蜥 7.9&#xff08;平替CentOS7.9&#xff09;&#xff1b;②CPU&#xff1a;x86&#xff1b;③用户&#xff1a;root。 预研初衷&#xff1a;现在很多项目有国产化的要求&#…

Docker 安装与配置 Nginx

摘要 1、本文全面介绍了如何在 Docker 环境中安装和配置 Nginx 容器。 2、文中详细解释了如何设置 HTTPS 安全连接及配置 Nginx 以实现前后端分离的代理服务。 2、同时&#xff0c;探讨了通过 IP 和域名两种方式访问 Nginx 服务的具体配置方法 3、此外&#xff0c;文章还涵…

C语言格式输出

1.转换字符说明&#xff1a; 2.常用的打印格式&#xff1a; 在 C 语言中&#xff0c;格式输出主要依靠 printf 函数来实现。以下是一些 C 语言格式输出的代码举例及相关说明。 printf("%2d"&#xff0c;123)&#xff0c;因为输出的部分有三位数&#xff0c;但是要求…

yolov5核查数据标注漏报和误报

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、误报二、漏报三、源码总结 前言 本文主要用于记录数据标注和模型预测之间的漏报和误报思想及其源码 提示&#xff1a;以下是本篇文章正文内容&#xff0c;…

Word如何插入图片并移动到某个位置

Word如何插入图片并移动到某一个位置 新建word→插入→图片 选择合适的位置→选择图片→打开 点击图片→布局选项→选择文字环绕下的任意一个→固定在页面上 点击图片就可以将图片移动到任意位置

【prometheus】【blackbox_exporter】grafna导入blackbox_exporter看板配置

1、进入到grafana看板&#xff0c;选择合适的看板模版 地址&#xff1a;https://grafana.com/grafana/dashboards/ 在搜索框中输入 blackbox_exporter,找到合适的模版&#xff0c;如下图所示&#xff1a; 2、点击并下载对应看板JSON数据 3、在grafana的页面进行导入操作 3.1…

微服务面试题:分布式事务和服务监控

&#x1f9d1; 博主简介&#xff1a;CSDN博客专家&#xff0c;历代文学网&#xff08;PC端可以访问&#xff1a;https://literature.sinhy.com/#/?__c1000&#xff0c;移动端可微信小程序搜索“历代文学”&#xff09;总架构师&#xff0c;15年工作经验&#xff0c;精通Java编…

wx015基于springboot+vue+uniapp的经济新闻资讯的设计与实现

开发语言&#xff1a;Java框架&#xff1a;springbootuniappJDK版本&#xff1a;JDK1.8服务器&#xff1a;tomcat7数据库&#xff1a;mysql 5.7&#xff08;一定要5.7版本&#xff09;数据库工具&#xff1a;Navicat11开发软件&#xff1a;eclipse/myeclipse/ideaMaven包&#…

获取用户详细信息-ThreadLocal优化

Thread全局接口可用&#xff0c;不用再重复编写。所以为了代码的复用&#xff0c;使用Thread。把之前的内容&#xff08;函数的参数和map与username&#xff09;注释掉&#xff0c;换为Thread传过来的内容&#xff08;map与username&#xff09;。 因为Thread需要在拦截器里面…

【论文阅读笔记】IceNet算法与代码 | 低照度图像增强 | IEEE | 2021.12.25

目录 1 导言 2 相关工作 A 传统方法 B 基于CNN的方法 C 交互方式 3 算法 A 交互对比度增强 1)Gamma estimation 2)颜色恢复 3)个性化初始η B 损失函数 1)交互式亮度控制损失 2)熵损失 3)平滑损失 4)总损失 C 实现细节 4 实验 5 IceNet环境配置和运行 1 下载…

git环境配置用户与秘钥

git环境配置用户与秘钥 git环境配置git配置用户名与邮箱git配置秘钥 git环境配置 已经安装git后环境配置 git配置用户名与邮箱 查看git版本 git -v查看git配置环境 git config --global --list第一次未配置时会报无法找到配置文件 全局配置git用户名 git config --glob…

logback日志框架源码分析

目录 (一)入口:slf4j选择日志框架 (二)日志框架初始化 (1)logback的3种配置方式 a、BasicConfigurator默认配置 b、SPI方式配置的Configurator实现类 c、通过配置文件初始化 (2)xml配置文件初始化 (三)Logger的创建 (四)打印日志 本文源码基于:logback版…

SpringBoot整合篇 05、Springboot整合Redission

文章目录 前言Redission详细配置步骤pom依赖application.yaml配置类CacheConfigEnvironmentContext RedissionController单测 前言 本篇博客是SpringBoot整合Redission&#xff0c;若文章中出现相关问题&#xff0c;请指出&#xff01; 所有博客文件目录索引&#xff1a;博客…