当前位置: 首页 > news >正文

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
  • 编译并运行程序,观察不同线程同步机制的效果。

在这里插入图片描述

相关文章:

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

实现思路 QThread 类简介&#xff1a; QThread 是 Qt 中用于多线程编程的基础类。可以通过继承 QThread 并重写 run() 方法来创建自定义的线程逻辑。新线程的执行从 run() 开始&#xff0c;调用 start() 方法启动线程。 掷骰子的多线程应用程序&#xff1a; 创建一个 DiceThre…...

【JVM】深入了解Java虚拟机-------内存划分、类加载机制、垃圾回收机制

目录 什么是JVM? 内存划分&#xff1a; 1.堆 &#xff08;共享&#xff09; 2.栈 &#xff08;私有&#xff09; 3.元数据区&#xff08;共享&#xff09; 4.程序计数器&#xff08;私有&#xff09; 示例&#xff1a; JVM 类加载 一.类加载过程 1.加载 2.验证 3.…...

k8s部署juicefs

操作系统k8smysqlminiojuicefs内核centos8.21.19.18.0.39RELEASE.2023-12-20T01-00-02Zv0.19.04.18.0-193.el8.x86_64 本文k8s较老采用老版本的juicefs&#xff0c;中间件也都是部署在k8s上。测试是否能成功创建动态pvc挂在到测试pod当中并查看到数据信息。一些偏理论知识就不多…...

【ArcGIS微课1000例】0136:制作千层饼(DEM、影像、等高线、山体阴影图层)

文章目录 一、效果展示二、数据准备三、制作过程1. 打开软件2. 制作DEM图层3. 制作影像层4. 制作TIN层5. 制作等高线层四、注意事项一、效果展示 二、数据准备 订阅专栏后,从专栏配套案例数据包中的0136.rar中获取。 1. dem 2. 影像 3. 等高线 4. tin 三、制作过程 1. 打开软…...

Ajax数据爬取

有时我们用requests 抓取页面得到的结果&#xff0c;可能和在浏览器中看到的不一样:在浏览器中可以看到正常显示的页面数据&#xff0c;而使用requests 得到的结果中并没有这些数据。这是因为 requests 获取的都是原始 HTML 文档&#xff0c;而浏览器中的页面是JavaScript 处理…...

快速上手大模型的对话生成

本项目使用0.5B小模型&#xff0c;结构和大模型别无二致&#xff0c;以方便在如CPU设备上快速学习和上手大模型的对话上传 #mermaid-svg-Z86hUiQZ0hg9BVji {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-Z86hUiQZ0h…...

DateTimeExtensions:一个轻量C#的开源DateTime扩展方法库

推荐一个专门为System.DateTime编写的扩展方法库。 01 项目简介 该项目主要是为System.DateTime和System.DateTimeOffset的编写的扩展方法&#xff0c;包括自然日期差值的文本表示&#xff08;精确和人性化四舍五入&#xff09;、多个时区的节假日和工作日计算。 核心扩展方…...

题解:监控屏幕调整问题

问题描述 Reca 公司生产高端显示器&#xff0c;其中最受欢迎的型号是 AB999。屏幕尺寸为 $x \times y$ 的比例。由于某些生产特性&#xff0c;屏幕参数总是整数。最终&#xff0c;屏幕边长比例 $x:y$ 需要适应用户的需求。 为了满足用户需求&#xff0c;公司需要调整屏幕尺寸…...

C语言----指针

目录 1.概念 2.格式 3.指针操作符 4.初始化 1. 将普通变量的地址赋值给指针变量 a. 将数组的首地址赋值给指针变量 b. 将指针变量里面保存的地址赋值给另一个指针变量 5.指针运算 5.1算术运算 5.2 关系运算 指针的大小 总结&#xff1a; 段错误 指针修饰 1. con…...

树莓派之旅-在wsl-x86-64 上进行树莓派的交叉编译

前情提要&#xff1a; 想把自己花里胡哨的终端丢到树莓派上去&#xff0c;可是树莓派算力不够&#xff0c;编译时间过于漫长 交叉编译 定义网上有&#xff0c;懒得复制了&#xff0c;大概就是在本机电脑上编译目标平台的可执行文件 这里的目标平台是树莓派 使用 uname -m …...

nature reviews genetics | 需要更多的针对不同种族的癌症基因组图谱研究,促进精准治疗和维护治疗公平权益

–https://doi.org/10.1038/s41576-024-00796-w Genomic landscape of cancer in racially and ethnically diverse populations 研究团队和单位 Ulrike Peters–Public Health Sciences Division, Fred Hutchinson Cancer Center Claire E. Thomas–Public Health Scienc…...

代码随想录算法训练营day18

代码随想录算法训练营 —day18 文章目录 代码随想录算法训练营前言一、530.二叉搜索树的最小绝对差递归法迭代法 二、501.二叉搜索树中的众数普通二叉树的方法递归法中序迭代法 三、 236. 二叉树的最近公共祖先递归法 总结 前言 今天是算法营的第18天&#xff0c;希望自己能够…...

Kafka安全优化文档:漏洞修复到安全加固

文章目录 1.1.漏洞修复1.1.1.Apache Kafka反序列化漏洞1.1.2.pm2-kafka代码执行漏洞1.1.3.Apache Kafka安全绕过漏洞1.1.4.Apache Kafka Distribution - Schema Repository跨站请求伪造漏洞1.1.5.Apache Kafka输入验证错误漏洞的补丁1.1.6.Apache Kafka信息泄露漏洞1.1.7.Apach…...

Markdown如何添加任务列表-复选框的添加

Markdown如何添加任务列表-复选框的添加 前言语法讲解使用场景及应用实例代码整和渲染结果小结其他文章快来试试吧☺️ Markdown如何添加任务列表-复选框的添加&#x1f448;点击这里也可查看 前言 To-do任务列表是一种很常见的时间管理工具&#xff0c;它适用于工作计划&…...

基于下垂控制的构网变换器功率控制【微电网变流器】【Simulink】

目录 主要内容 理论研究 整体模型 PQ计算模块 功率控制模块 PWM反馈模块 结果一览 下载链接 主要内容 该仿真针对微电网中分布式电源接入后产生的谐波影响&#xff0c;除了污染网络外&#xff0c;还会恶化微电网变流器输出电流&#xff0c;为了消除谐波影响&a…...

AI定义汽车/跨域融合/整车智能,汽车智能化2.0时代新机会来了

汽车智能化2.0&#xff0c;产业正在发生深度变革。 一方面&#xff0c;AI大模型开始在多个域同步赋能智能汽车&#xff0c;从智能座舱到智能驾驶&#xff0c;再到底盘域&#xff0c;AI大模型正在快速推动汽车变革为超级智能体&#xff0c;AI定义汽车时代开始来临。 另一方面&…...

(leetcode算法题)10. 正则表达式匹配

10. 正则表达式匹配 - 力扣&#xff08;LeetCode&#xff09; 此题的要求一个字符串 s 和一个字符规律 p之间支持 . 和 * 的正则表达式匹配 . 匹配任意单个字符 * 匹配零个或多个前面的那一个元素 所谓匹配&#xff0c;是要涵盖 整个 字符串 s 的&#xff0c;而不是部分字符串…...

SpringCloudAlibaba实战入门之Sentinel服务降级和服务熔断(十五)

一、Sentinel概述 1、Sentinel是什么 随着微服务的流行,服务和服务之间的稳定性变得越来越重要。Sentinel 以流量为切入点,从流量控制、熔断降级、系统负载保护等多个维度保护服务的稳定性。 一句话概括:sentinel即Hystrix的替代品,官网: https://sentinelguard.io/zh…...

使用爬虫技术获取网页中的半结构化数据

目录 前言1. 半结构化数据与爬虫技术简介1.1 半结构化数据的定义与特性1.2 爬虫技术的基本原理 2. 爬取半结构化数据的实现过程2.1 明确目标与准备2.2 发送HTTP请求2.3 解析网页内容2.4 动态内容的处理2.5 数据存储与清洗 3. 技术挑战与应对策略3.1 处理反爬机制3.2 提高爬取效…...

2025/1/1 路由期末复习作业二

呼呼呼祝大家元旦节快乐啦&#xff01;&#xff08;我顶着我超重的黑眼圈说&#xff09; 昨天一个人在寝室一边吃泡面&#xff0c;一边看步步惊心&#xff0c;一边吃一边哭呜呜呜呜呜若曦为什么不和八爷在一起好好爱&#xff0c;就因为他不当皇帝蛮&#xff01;难测最是帝王心…...

Docker 离线安装指南

参考文章 1、确认操作系统类型及内核版本 Docker依赖于Linux内核的一些特性&#xff0c;不同版本的Docker对内核版本有不同要求。例如&#xff0c;Docker 17.06及之后的版本通常需要Linux内核3.10及以上版本&#xff0c;Docker17.09及更高版本对应Linux内核4.9.x及更高版本。…...

ubuntu搭建nfs服务centos挂载访问

在Ubuntu上设置NFS服务器 在Ubuntu上&#xff0c;你可以使用apt包管理器来安装NFS服务器。打开终端并运行&#xff1a; sudo apt update sudo apt install nfs-kernel-server创建共享目录 创建一个目录用于共享&#xff0c;例如/shared&#xff1a; sudo mkdir /shared sud…...

STM32+rt-thread判断是否联网

一、根据NETDEV_FLAG_INTERNET_UP位判断 static bool is_conncected(void) {struct netdev *dev RT_NULL;dev netdev_get_first_by_flags(NETDEV_FLAG_INTERNET_UP);if (dev RT_NULL){printf("wait netdev internet up...");return false;}else{printf("loc…...

STM32标准库-DMA直接存储器存取

文章目录 一、DMA1.1简介1.2存储器映像1.3DMA框图1.4DMA基本结构1.5DMA请求1.6数据宽度与对齐1.7数据转运DMA1.8ADC扫描模式DMA 二、数据转运DMA2.1接线图2.2代码2.3相关API 一、DMA 1.1简介 DMA&#xff08;Direct Memory Access&#xff09;直接存储器存取 DMA可以提供外设…...

将对透视变换后的图像使用Otsu进行阈值化,来分离黑色和白色像素。这句话中的Otsu是什么意思?

Otsu 是一种自动阈值化方法&#xff0c;用于将图像分割为前景和背景。它通过最小化图像的类内方差或等价地最大化类间方差来选择最佳阈值。这种方法特别适用于图像的二值化处理&#xff0c;能够自动确定一个阈值&#xff0c;将图像中的像素分为黑色和白色两类。 Otsu 方法的原…...

Cloudflare 从 Nginx 到 Pingora:性能、效率与安全的全面升级

在互联网的快速发展中&#xff0c;高性能、高效率和高安全性的网络服务成为了各大互联网基础设施提供商的核心追求。Cloudflare 作为全球领先的互联网安全和基础设施公司&#xff0c;近期做出了一个重大技术决策&#xff1a;弃用长期使用的 Nginx&#xff0c;转而采用其内部开发…...

DBAPI如何优雅的获取单条数据

API如何优雅的获取单条数据 案例一 对于查询类API&#xff0c;查询的是单条数据&#xff0c;比如根据主键ID查询用户信息&#xff0c;sql如下&#xff1a; select id, name, age from user where id #{id}API默认返回的数据格式是多条的&#xff0c;如下&#xff1a; {&qu…...

多模态大语言模型arxiv论文略读(108)

CROME: Cross-Modal Adapters for Efficient Multimodal LLM ➡️ 论文标题&#xff1a;CROME: Cross-Modal Adapters for Efficient Multimodal LLM ➡️ 论文作者&#xff1a;Sayna Ebrahimi, Sercan O. Arik, Tejas Nama, Tomas Pfister ➡️ 研究机构: Google Cloud AI Re…...

【JavaWeb】Docker项目部署

引言 之前学习了Linux操作系统的常见命令&#xff0c;在Linux上安装软件&#xff0c;以及如何在Linux上部署一个单体项目&#xff0c;大多数同学都会有相同的感受&#xff0c;那就是麻烦。 核心体现在三点&#xff1a; 命令太多了&#xff0c;记不住 软件安装包名字复杂&…...

【Oracle】分区表

个人主页&#xff1a;Guiat 归属专栏&#xff1a;Oracle 文章目录 1. 分区表基础概述1.1 分区表的概念与优势1.2 分区类型概览1.3 分区表的工作原理 2. 范围分区 (RANGE Partitioning)2.1 基础范围分区2.1.1 按日期范围分区2.1.2 按数值范围分区 2.2 间隔分区 (INTERVAL Partit…...