Qt互斥锁(QMutex)的使用、QMutexLocker的使用
Qt互斥锁【QMutex】的使用、QMutexLocker的使用
- Chapter1 Qt互斥锁(QMutex)的使用、QMutexLocker的使用
- 一、QMutexLocker和QMutex实现示例图
- 二、QMutex和QMutexLocker的关系(个人理解)
- 三、QMutex使用和QMutexLocker使用
- 1.QMutex的使用
- 2.QMutexLocker的使用
- 四、检验QMutexLocker是否将传入的互斥锁锁定
- 1.操作解释
- 2.CMoveFuncClass(使用moveToThread实现,使用QMutexLocker)
- 3.CThread类(继承QThread实现,单纯使用QMutex)
- 4.CMainWindow调用类
- 总结
- 相关文章
Chapter1 Qt互斥锁(QMutex)的使用、QMutexLocker的使用
原文链接:https://blog.csdn.net/wj584652425/article/details/123585126
一、QMutexLocker和QMutex实现示例图
下图为检测QMutexLocker是否上锁成功的示例图(两个线程使用同一个QMutex),源码在文章第四节(源码含详细注释)。
下图为不同QMutex运行时的效果(该图表明两个线程无关,并非sleep影响了另一个线程的运行)
二、QMutex和QMutexLocker的关系(个人理解)
互斥锁(QMutex)在使用时需要在进入和结束的时候使用对应的函数锁定和解锁。在简单的程序中还好,但是在结构复杂的程序中因为需要手动锁定和解锁,很容易忽略细节而出现问题,于是为了应对这种情况QMutexLocker便诞生了(为了简化简化互斥锁的锁定和解锁)。
QMutexLocker通常创建为局部变量,QMutexLocker在创建时传入一个并未锁定(若是锁定可用relock重新锁定或unlock解锁)的QMutex指针变量,并且会将QMutex变量锁定,在释放时会将QMutex变量解锁。(QMutexLocker创建时将传入的QMutex锁定,释放时将传入的QMutex解锁)
三、QMutex使用和QMutexLocker使用
1.QMutex的使用
void CThread::run()
{//互斥锁锁定m_mutex->lock();//输出当前线程的线程IDqDebug() << QThread::currentThreadId();//互斥锁解锁m_mutex->unlock();
}
2.QMutexLocker的使用
void CThread::run()
{//创建QMutexLocker的局部变量,并将类中互斥锁指针传入(此处互斥锁被locker锁定)QMutexLocker locker(m_mutex);qDebug() << QThread::currentThreadId();//当locker作用域结束locker将互斥锁解锁
}
通过1、2的代码比较,我们会发现QMutexLocker的代码中没有手动调用锁定和解锁,由此可看出MutexLocker简化了互斥锁的锁定和解锁。
四、检验QMutexLocker是否将传入的互斥锁锁定
1.操作解释
使用两种实现方法完全不同线程测试
两个线程使用同一个互斥锁
一个线程使用QMutexLocker一个线程单纯使用QMutex
2.CMoveFuncClass(使用moveToThread实现,使用QMutexLocker)
CMoveFuncClass.h
#ifndef CMOVEFUNCCLASS_H
#define CMOVEFUNCCLASS_H#include <QObject>
#include <QMutex>class CMoveFuncClass : public QObject
{Q_OBJECT
public:explicit CMoveFuncClass(QObject *parent = nullptr);~CMoveFuncClass();void setMutex(QMutex *mutex);public slots:void doSomething();private:QMutex * m_mutex; //定义一个互斥锁变量
};#endif // CMOVEFUNCCLASS_H
CMoveFuncClass.cpp
#include "CMoveFuncClass.h"#include <QDebug>
#include <QThread>CMoveFuncClass::CMoveFuncClass(QObject *parent): QObject(parent)
{
}CMoveFuncClass::~CMoveFuncClass()
{
}void CMoveFuncClass::doSomething()
{//创建QMutexLocker的局部变量,并将类中互斥锁指针传入(此处互斥锁被locker锁定)QMutexLocker locker(m_mutex);qDebug() << "我的实现方法为moveToThread" <<"开始3秒睡眠" << "使用QMutexLocker";qDebug() << "线程ID:" << QThread::currentThreadId();QThread::sleep(3); //设置线程睡眠3秒(单位为秒)qDebug() << "我的实现方法为moveToThread" <<"线程运行完成,结束睡眠\n\n";//当locker作用域结束locker将互斥锁解锁
}void CMoveFuncClass::setMutex(QMutex *mutex)
{m_mutex = mutex;
}
3.CThread类(继承QThread实现,单纯使用QMutex)
CThread.h
#ifndef CTHREAD_H
#define CTHREAD_H#include <QObject>
#include <QThread>
#include <QMutex>
#include <QWaitCondition>class CThread : public QThread
{Q_OBJECT
public:explicit CThread(QObject *parent = nullptr);~CThread();void run();void setMutex(QMutex *mutex);private:QMutex * m_mutex; //定义一个线程锁变量};#endif // CTHREAD_H
CThread.cpp
#include "CThread.h"
#include <QDebug>CThread::CThread(QObject *parent): QThread(parent)
{
}CThread::~CThread()
{
}void CThread::run()
{//互斥锁上锁m_mutex->lock();qDebug() << "我的实现方法为继承QThread" << "开始3秒睡眠" << "单纯使用QMutex";qDebug() << "线程ID:" << QThread::currentThreadId();QThread::sleep(3); //设置线程睡眠3秒(单位为秒)qDebug() << "我的实现方法为继承QThread" <<"线程运行完成,结束睡眠";//互斥锁解锁m_mutex->unlock();
}void CThread::setMutex(QMutex *mutex)
{m_mutex = mutex;
}
4.CMainWindow调用类
CMainWindow.h
#ifndef CMAINWINDOW_H
#define CMAINWINDOW_H#include <QMainWindow>
#include "CThread.h"
#include "CMoveFuncClass.h"namespace Ui {
class CMainWindow;
}class CMainWindow : public QMainWindow
{Q_OBJECTpublic:explicit CMainWindow(QWidget *parent = 0);~CMainWindow();signals:void startMoveThread();private slots:void on_startBtn_clicked(); //触发方法二函数的信号private:Ui::CMainWindow *ui;CThread *m_cThread; //方法一指针CMoveFuncClass *m_moveFunc; //方法二指针QThread *m_thread; //方法二所移至的线程指针QMutex *m_mutex; //两个线程使用的线程锁
};#endif // CMAINWINDOW_H
CMainWindow.cpp
#include "CMainWindow.h"
#include "ui_CMainWindow.h"#include <QDebug>CMainWindow::CMainWindow(QWidget *parent) :QMainWindow(parent),ui(new Ui::CMainWindow)
{ui->setupUi(this);/方法一/////new出CThread对象m_cThread = new CThread;/方法二/////new一个moveToThread的接收线程并启动m_thread = new QThread;//new出CMoveFuncClass对象m_thread->start(); //一定记得启动,否则运行不了m_moveFunc = new CMoveFuncClass;//连接相应信号槽connect(this, &CMainWindow::startMoveThread, m_moveFunc, &CMoveFuncClass::doSomething);connect(m_thread, &QThread::finished, m_moveFunc, &QObject::deleteLater);//将对象移至线程m_moveFunc->moveToThread(m_thread);//创建线程共用的互斥锁m_mutex = new QMutex;//下方为m_mutex的地方更改为new QMutex,则能实现第一节,第二张图的效果m_cThread->setMutex(m_mutex);m_moveFunc->setMutex(m_mutex);
}CMainWindow::~CMainWindow()
{delete m_mutex;delete m_moveFunc;m_thread->exit();m_thread->wait(1);delete m_thread;m_cThread->exit();m_cThread->wait(1);delete m_cThread;delete ui;
}void CMainWindow::on_startBtn_clicked()
{//通过start启动方法一线程m_cThread->start();//发送信号启动方法二线程emit startMoveThread();
}
运行上方的代码(第一节,第一张效果图)可看出,使用QMutexLocker的线程首先运行,且代码中无锁定和解锁的操作,但另外一个线程依然等该线程运行完成后运行,由此可看出,使用QMutexLocker是实现了互斥锁的锁定和解锁的。
总结
QMutexLocker提供的简化互斥锁锁定和解锁的机制在很多时候时蛮方便的,在使用互斥锁的地方使用QMutexLocker会减去许多安全隐患;不过在多线程循环输出ABC的时候好像就不适合该方法。所以使用类似的类还得按情况而定
相关文章
启动QThread线程的两种方法(含源码+注释)
Qt互斥锁(QMutex)、条件变量(QWaitCondition)讲解+QMutex实现多线程循环输出ABC(含源码+注释)
QSemaphore的使用+QSemaphore实现循环输出ABC(含源码+注释)
QRunnable线程、QThreadPool(线程池)的使用(含源码+注释)
Qt读写锁(QReadWriteLock)的使用、读写锁的验证(含源码+注释)
Qt读写锁(QWriteLocker、QReadLocker)的理解和使用(含部分源码)
Qt之线程运行指定函数(含源码+注释,优化速率)
友情提示——哪里看不懂可私哦,让我们一起互相进步吧
(创作不易,请留下一个免费的赞叭 谢谢 o/)
注:文章为作者编程过程中所遇到的问题和总结,内容仅供参考,若有错误欢迎指出。
注:如有侵权,请联系作者删除
相关文章:
Qt互斥锁(QMutex)的使用、QMutexLocker的使用
Qt互斥锁【QMutex】的使用、QMutexLocker的使用 Chapter1 Qt互斥锁(QMutex)的使用、QMutexLocker的使用一、QMutexLocker和QMutex实现示例图二、QMutex和QMutexLocker的关系(个人理解)三、QMutex使用和QMutexLocker使用1.QMutex的使用2.QMutexLocker的使…...
具身智能(Embodied AI)的物理交互基准测试:构建真实世界的智能体评估体系
文章目录 引言:从虚拟到物理的智能跃迁一、具身智能测试体系设计1.1 评估维度矩阵1.2 测试平台技术栈二、核心测试场景构建2.1 基础运动能力测试集2.2 复杂操作任务设计三、物理仿真引擎关键技术3.1 高精度接触力学模型3.2 传感器噪声模拟四、评估指标体系4.1 量化指标公式4.2…...
Javaweb后端数据库多表关系一对多,外键,一对一
多表关系 一对多 多的表里,要有一表里的主键 外键 多的表上,添加外键 一对一 多对多 案例...
鸿蒙 ArkUI 实现敲木鱼小游戏
敲木鱼是一款具有禅意的趣味小游戏,本文将通过鸿蒙 ArkUI 框架的实现代码,逐步解析其核心技术点,包括动画驱动、状态管理、音效震动反馈等。 一、架构设计与工程搭建 1.1 项目结构解析 完整项目包含以下核心模块: ├── entry…...
cv2.solvePnP 报错 求相机位姿
目录 报错信息及解决: cv2.solvePnP 使用例子: 设置初始值效果也不好 cv2.projectPoints 函数效果不好 报错信息及解决: File "/shared_disk/users/lbg/project/human_4d/nlf_pose/render_demo_pkl2_cal.py", line 236, in <…...
Linux实操——在服务器上直接从百度网盘下载(/上传)文件
Linux Linux实操——在服务器上直接从百度网盘下载(/上传)文件 文章目录 Linux前言一、下载并安装bypy工具二、认证并授权网盘账号三、将所需文件转移至目的文件夹下四、下载文件五、上传文件六、更换绑定的百度云盘账户 前言 最近收到一批很大的数据&…...
2004-2024年光刻机系统及性能研究领域国内外发展历史、差距、研究难点热点、进展突破及下一个十年研究热点方向2025.2.27
一.光刻机概述 1.1 定义与原理 光刻机是 集成电路芯片制造的核心设备 ,其工作原理基于 光学成像和化学反应 。它通过 曝光系统 将掩模版上的图形精确地转移到涂覆于硅片表面的光刻胶上。这个过程涉及复杂的物理和化学反应,主要包括以下几个步骤: 涂胶 :在硅片表面均匀涂抹…...
请求Geoserver的WTMS服务返回200不返回图片问题-跨域导致
今天碰到个奇怪问题,改了个页面标题再打包布署GeoServer发现调用WTMS服务失败,请求返回状态码200,返回包大小0,使用postman模拟请求是可以正常返回图片的。 跟之前版本对比如下: 正常Response请求: HTTP/1.1 200X-Fr…...
ubuntu配置jmeter
1.前提准备 系统 ubuntu server 22.04 前提条件:服务器更新apt与安装lrzsz:更新apt: sudo apt update安装lrzsz: 命令行下的上传下载文件工具 sudo apt install lrzszsudo apt install zip2.安装jemeter 2.1.下载jdk17 输入命令…...
《Qt动画编程实战:轻松实现头像旋转效果》
《Qt动画编程实战:轻松实现头像旋转效果》 Qt 提供了丰富的动画框架,可以轻松实现各种平滑的动画效果。其中,旋转动画是一种常见的 UI 交互方式,广泛应用于加载指示器、按钮动画、场景变换等。本篇文章将详细介绍如何使用 Qt 实现…...
【Mac电脑本地部署Deepseek-r1:详细教程与Openwebui配置指南】
文章目录 前言电脑配置:安装的Deepseek版本:使用的UI框架:体验效果展示:本地部署体验总结 部署过程Ollama部署拉取模型运行模型Openwebui部署运行Ollama服务在Openwebui中配置ollama的服务 后话 前言 deepseek最近火的一塌糊涂&a…...
DeepSeek开源技术全景解析:从硬件榨取到AI民主化革命
DeepSeek开源技术全景解析:从硬件榨取到AI民主化革命 一、开源周核心成果概览 2025年2月24日启动的"开源周"计划,DeepSeek团队连续发布三项底层技术突破: FlashMLA(2.24):动态资源调度算法&am…...
WPF12-MVVM
目录 1. 什么是MVVM2. 实现简单MVVM2.1. Part 12.2. Part 21. 什么是MVVM MVVM 是 Model-View-ViewModel 的缩写,是一种用于构建用户界面的设计模式,是一种简化用户界面的事件驱动编程方式。 MVVM 的目标是实现用户界面和业务逻辑之间的彻底分离,以便更好地管理和维护应用…...
一个原教旨的多路径 TCP
前面提到过 ECMP 和 TCP 之间的互不友好,pacing 收益和中断开销的互斥,在事实上阻碍了 packet-based LB 的部署,也限制了交换机,服务器的并发性能,同时潜在增加了 bufferbloat 的概率,而适用 packet-based …...
跟着AI学vue第十三章
第十三章:技术传承与行业影响力塑造 到了这个阶段,你已经在Vue技术领域积累了深厚的经验,拥有了较强的技术实力。此时,你的重点将是把自己的知识和经验传递给更多人,在行业内树立起影响力,推动整个Vue技术…...
labview中VISA串口出现异常的解决方案
前两天在做项目时发现,当用VISA串口读取指令时出现了回复异常的情况,不管发什么东西就一直乱回,针对这个情况,后面在VISA串口中加了一个VISA寄存器清零的函数。加了之后果然好多了,不会出现乱回的情况,但是…...
StableDiffusion本地部署 2
StableDiffusion本地部署 为了做这个事,这是第5篇文章了,可谓是做足了准备。开干! 强烈建议把我之前发的文章看一看,不然你会有点迷迷糊糊的。 整体思路 捋一捋思路: 下载三个东西,webui,py…...
unity学习61:UI布局layout
目录 1 布局 layout 1.1 先准备测试UI,新增这样一组 panel 和 image 1.2 新增 vertical layout 1.3 现在移动任意一个image 都会影响其他 1.3.1 对比 如果没有这个,就会是覆盖效果了 1.3.2 对比 如果没有这个,就会是覆盖效果了 1.4 总结…...
BRD4缺失通过GRP78灭活内质网应激,延缓脱氢表雄酮诱导的卵巢颗粒细胞凋亡
近日,一项由宁波大学医学院附属妇女儿童医院与同济大学附属东方医院妇产科合作的研究,揭示了BRD4(Bromodomain-containing protein 4)在PCOS中的重要作用,以及其与内质网应激(ERS)的复杂关系。值…...
Jmeter插件下载及安装
1、在Jmeter官网(Install :: JMeter-Plugins.org)下载所需插件 2、将下载的插件复制到jmeter文件下的lib/ext文件里(PS:D:\Jmeter\apache-jmeter-5.6.2\lib\ext) 3、打开Jmeter,选择 选项----Plugins Manag…...
浅谈 React Hooks
React Hooks 是 React 16.8 引入的一组 API,用于在函数组件中使用 state 和其他 React 特性(例如生命周期方法、context 等)。Hooks 通过简洁的函数接口,解决了状态与 UI 的高度解耦,通过函数式编程范式实现更灵活 Rea…...
shell脚本--常见案例
1、自动备份文件或目录 2、批量重命名文件 3、查找并删除指定名称的文件: 4、批量删除文件 5、查找并替换文件内容 6、批量创建文件 7、创建文件夹并移动文件 8、在文件夹中查找文件...
java 实现excel文件转pdf | 无水印 | 无限制
文章目录 目录 文章目录 前言 1.项目远程仓库配置 2.pom文件引入相关依赖 3.代码破解 二、Excel转PDF 1.代码实现 2.Aspose.License.xml 授权文件 总结 前言 java处理excel转pdf一直没找到什么好用的免费jar包工具,自己手写的难度,恐怕高级程序员花费一年的事件,也…...
TRS收益互换:跨境资本流动的金融创新工具与系统化解决方案
一、TRS收益互换的本质与业务逻辑 (一)概念解析 TRS(Total Return Swap)收益互换是一种金融衍生工具,指交易双方约定在未来一定期限内,基于特定资产或指数的表现进行现金流交换的协议。其核心特征包括&am…...
3403. 从盒子中找出字典序最大的字符串 I
3403. 从盒子中找出字典序最大的字符串 I 题目链接:3403. 从盒子中找出字典序最大的字符串 I 代码如下: class Solution { public:string answerString(string word, int numFriends) {if (numFriends 1) {return word;}string res;for (int i 0;i &…...
【开发技术】.Net使用FFmpeg视频特定帧上绘制内容
目录 一、目的 二、解决方案 2.1 什么是FFmpeg 2.2 FFmpeg主要功能 2.3 使用Xabe.FFmpeg调用FFmpeg功能 2.4 使用 FFmpeg 的 drawbox 滤镜来绘制 ROI 三、总结 一、目的 当前市场上有很多目标检测智能识别的相关算法,当前调用一个医疗行业的AI识别算法后返回…...
学校时钟系统,标准考场时钟系统,AI亮相2025高考,赛思时钟系统为教育公平筑起“精准防线”
2025年#高考 将在近日拉开帷幕,#AI 监考一度冲上热搜。当AI深度融入高考,#时间同步 不再是辅助功能,而是决定AI监考系统成败的“生命线”。 AI亮相2025高考,40种异常行为0.5秒精准识别 2025年高考即将拉开帷幕,江西、…...
人机融合智能 | “人智交互”跨学科新领域
本文系统地提出基于“以人为中心AI(HCAI)”理念的人-人工智能交互(人智交互)这一跨学科新领域及框架,定义人智交互领域的理念、基本理论和关键问题、方法、开发流程和参与团队等,阐述提出人智交互新领域的意义。然后,提出人智交互研究的三种新范式取向以及它们的意义。最后,总结…...
使用LangGraph和LangSmith构建多智能体人工智能系统
现在,通过组合几个较小的子智能体来创建一个强大的人工智能智能体正成为一种趋势。但这也带来了一些挑战,比如减少幻觉、管理对话流程、在测试期间留意智能体的工作方式、允许人工介入以及评估其性能。你需要进行大量的反复试验。 在这篇博客〔原作者&a…...
解读《网络安全法》最新修订,把握网络安全新趋势
《网络安全法》自2017年施行以来,在维护网络空间安全方面发挥了重要作用。但随着网络环境的日益复杂,网络攻击、数据泄露等事件频发,现行法律已难以完全适应新的风险挑战。 2025年3月28日,国家网信办会同相关部门起草了《网络安全…...
