Qt的互斥量用法

news2024/10/1 15:42:15

目的

互斥量的概念

互斥量是一个可以处于两态之一的变量:解锁和加锁。这样,只需要一个二进制位表示它,不过实际上,常常使用一个整型量,0表示解锁,而其他所有的值则表示加锁。互斥量使用两个过程。当一个线程(或进程)需要访问临界区时,它调用mutex_lock。如果该互斥量当前是解锁的(即临界区可用),此调用成功,调用线程可以自由进入该临界区。
另一方面,如果该互斥量已经加锁,调用线程被阻塞,直到在临界区中的线程完成并调用mutex_unlock。如果多个线程被阻塞在该互斥量上,将随机选择一个线程并允许它获得锁。

QMutex的用法

QMutex各QMutexLocker是基于互斥量的线程同步类,QMutex定义的实例是一个互斥量,QMutex主要提供了3个函数。
lock:
锁定互斥量,如果另外一个线程锁定了这个互斥量,它将阻塞执行直到其它线程解锁这个互斥量。
unlock:
解锁一个互斥量,需要与lock()配对使用。
tryLock():
试图锁定一个互斥量,如果成功锁定就返回true,如果其它线程已经锁定了这一个互斥量,就返回false,但不阻塞程序执行。
QMutexLocker:
是另外一个简化的互斥量处理的类。QMutexLocker的构造函数接受一个互斥量作为参数,将其锁定,QMutexLocker的析构函数则将此互斥量解锁。

例子

下面通过实现,两个程序对数量进行累加,演示互斥量的用法:

业务类:

#include "business.h"
#include <QDebug>
#include <QThread>
#include <QDateTime>
int Business::s_num = 0;
QMutex Business::s_mutex;
Business::Business(QObject *parent) : QObject(parent)
{
}
int Business::getNum()
{
    return s_num;
}
void Business::addNum()
{
    //qDebug()<<"enter function addNum currentThreadId=" << QThread::currentThreadId()
    //       <<" currentTime="<<QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss.zzz");
    s_mutex.lock();
    s_num++;
    qDebug()<<"s_num="<<s_num;
    s_mutex.unlock();
    //qDebug()<<"exit function addNum currentThreadId=" << QThread::currentThreadId()
    //       <<" currentTime="<<QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss.zzz");
}
int Business::slot_getNum()
{
    return this->getNum();
}
void Business::slot_addNum()
{
    this->addNum();
}

线程类

#include "businessInThread.h"
BusinessInThread::BusinessInThread(QObject *parent) : QObject(parent)
{
    m_pWorkerThread = new QThread();
    m_pBusiness = new Business();
    m_pBusiness->moveToThread(m_pWorkerThread);
    connect(m_pWorkerThread, &QThread::finished, m_pBusiness, &QObject::deleteLater);
    connect(this, &BusinessInThread::signal_getNum, m_pBusiness,
            &Business::slot_getNum, Qt::BlockingQueuedConnection);
    connect(this, &BusinessInThread::signal_addNum, m_pBusiness, &Business::slot_addNum);
    m_pWorkerThread->start();
}
BusinessInThread::~BusinessInThread()
{
    m_pWorkerThread->quit();
    m_pWorkerThread->wait();
}
int BusinessInThread::getNum()
{
    return signal_getNum();
}
void BusinessInThread::addNum()
{
     signal_addNum();
}

主程序

#include <QCoreApplication>
#include "businessInThread.h"
int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
    BusinessInThread businessInThread1;
    BusinessInThread businessInThread2;
    for(int i = 0; i < 5; i++)
    {
       businessInThread1.addNum();
       businessInThread2.addNum();
    }
    return a.exec();
}

运行结果:

在这里插入图片描述

如果去掉锁的话,就会这样:
在这里插入图片描述

QMutextLocker的简化用法

这个函数:

void Business::addNum()
{
    //qDebug()<<"enter function addNum currentThreadId=" << QThread::currentThreadId()
    //       <<" currentTime="<<QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss.zzz");
    s_mutex.lock();
    s_num++;
    qDebug()<<"s_num="<<s_num;
    s_mutex.unlock();
    //qDebug()<<"exit function addNum currentThreadId=" << QThread::currentThreadId()
    //       <<" currentTime="<<QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss.zzz");
}

可以简化为:

void Business::addNum()
{
    //qDebug()<<"enter function addNum currentThreadId=" << QThread::currentThreadId()
    //       <<" currentTime="<<QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss.zzz");
    //s_mutex.lock();
    QMutexLocker Locker(&s_mutex);
    s_num++;
    qDebug()<<"s_num="<<s_num;
    //s_mutex.unlock();
    //qDebug()<<"exit function addNum currentThreadId=" << QThread::currentThreadId()
    //       <<" currentTime="<<QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss.zzz");
}

总结

在这里插入图片描述

互斥锁,就是只有锁定与解锁,两种状态,可以说,是最简单的锁,也是最实用的锁。

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

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

相关文章

ubuntu 24.04如何分配内存

24版与之前有一点不同&#xff0c;这里记录一下我的经历&#xff0c;希望有帮助 1.进入ubuntu直接试用&#xff0c;没有之前的安装向导&#xff08;如图&#xff09;&#xff0c;在屏幕的左上角会找到安装Ubuntu 2.分配内存 24的手动分配内存&#xff0c;不需要分配系统内存&…

IOT平台颜值天花板?延凡科技物联网平台让人惊叹不已

IOT平台颜值天花板&#xff1f;延凡科技物联网平台让人惊叹不已 在物联网的时代&#xff0c;AIOT平台凭借智能化的管理和决策能力&#xff0c;为多个行业带来了巨大的提升。本文将为大家介绍AIOT物联网平台的核心功能、应用场景以及它是如何改变我们的生活的。 平台简介 AIOT物…

二维环境下的TDOA测距定位的MATLAB代码,带中文注释

TDOA测距定位程序介绍 概述 本MATLAB程序实现了基于时间差到达&#xff08;TDOA&#xff09;技术的二维测距定位&#xff0c;能够处理4个或任意数量&#xff08;大于3个&#xff09;的锚节点。在无线定位和导航系统中&#xff0c;TDOA是一种常用的定位方法&#xff0c;通过测量…

一款免费开源的接口测试工具——ApiFox详细教程

前言 APIfox是一种功能强大的接口测试工具&#xff0c;它可以帮助用户轻松地进行REST API的自动化测试和文档编写。本文将从以下几个方面介绍APIfox的基本使用方法、特点和优势。 一、什么是APIfox&#xff1f; APIfox是一款基于Web的REST API测试工具&#xff0c;通过创建测…

论文笔记:LAFF 文本到视频检索的新基准

整理了ECCV2022 Lightweight Attentional Feature Fusion: A New Baseline for Text-to-Video Retrieval 论文的阅读笔记 背景模型问题定义LAFF(Lightweight Attention Feature Fusion)LAFF Block 实验消融实验可视化对比试验 这篇文章提出了一种新颖灵活的特征融合方式&#x…

初步认识产品经理

产品经理 思考问题的维度 1️⃣为什么要抓住核心用户&#xff1f; 所有和产品有关系的群体就是用户&#xff0c;存在共性和差异了解用户的付费点&#xff0c;更好的优化产品是否使用&#xff1a;&#xff08;目标用户-已使用产品&#xff1a;种子用户-尝鲜&#xff1b;核心用…

【Golang】深入解读Go语言中的错误(error)与异常(panic)

✨✨ 欢迎大家来到景天科技苑✨✨ &#x1f388;&#x1f388; 养成好习惯&#xff0c;先赞后看哦~&#x1f388;&#x1f388; &#x1f3c6; 作者简介&#xff1a;景天科技苑 &#x1f3c6;《头衔》&#xff1a;大厂架构师&#xff0c;华为云开发者社区专家博主&#xff0c;…

【Pyecharts】时间线柱状图x轴坐标重复出现并重叠

问题描述 如图右侧显示多的一列坐标 解决方案 降低pyecharts版本&#xff1a;pip install pyecharts2.0.5

ChatGPT与R语言融合技术在生态环境数据统计分析、绘图(回归和混合效应模型、多元统计分析)

自2022年GPT&#xff08;Generative Pre-trained Transformer&#xff09;大语言模型的发布以来&#xff0c;它以其卓越的自然语言处理能力和广泛的应用潜力&#xff0c;在学术界和工业界掀起了一场革命。在短短一年多的时间里&#xff0c;GPT已经在多个领域展现出其独特的价值…

vue2接入高德地图实现折线绘制、起始点标记和轨迹打点的完整功能(提供Gitee源码)

目录 一、申请密钥 二、安装element-ui 三、安装高德地图依赖 四、完整代码 五、运行截图 六、官方文档 七、Gitee源码 一、申请密钥 登录高德开放平台&#xff0c;点击我的应用&#xff0c;先添加新应用&#xff0c;然后再添加Key。 ​ 如图所示填写对应的信息&…

第十九章(自定义类型:结构体)

1. 结构体类型的声明 2. 结构体变量的创建和初始化 3. 结构成员访问操作符 4. 结构体内存对⻬ 5. 结构体传参 一、结构体类型的声明 1.1结构体的声明 struct student {int age;int id[10];char name[10]; };1.2 结构体变量的初始化 struct student {int age;char id[10…

YOLOv1代码复现(论文复现)

YOLOv1代码复现&#xff08;论文复现&#xff09; 本文所涉及所有资源均在传知代码平台可获取 文章目录 YOLOv1代码复现&#xff08;论文复现&#xff09;论文介绍主要内容实验部分卷积网络结构计算损失核心代码 缺点 论文介绍 该论文就是YOLOv1&#xff0c;YOLOv1是YOLO系列目…

大模型部署——NVIDIA NIM 和 LangChain 如何彻底改变 AI 集成和性能

DigiOps与人工智能 人工智能已经从一个未来主义的想法变成了改变全球行业的强大力量。人工智能驱动的解决方案正在改变医疗保健、金融、制造和零售等行业的企业运营方式。它们不仅提高了效率和准确性&#xff0c;还增强了决策能力。人工智能的价值不断增长&#xff0c;这从它处…

Ubuntu网卡配置

一、低阶版本配置网卡步骤:(如Ubuntu 16.04.2 LTS) 编辑配置文件interfaces,添加网卡配置信息 我这边以root用户登录进服务器,就不需要普通用户每次在命令前添加sudo vim /etc/network/interfaces 1.动态获取ip设置: auto ens3 # 网卡设备名称ens3 iface ens3 ine…

Tdesign TreeSelect 树形选择 多选

这里写自定义目录标题 小程序原生开发 Tdesign TreeSelect 树形选择 多选可以选择不同一级分类下的数据 小程序原生开发 Tdesign TreeSelect 树形选择 多选可以选择不同一级分类下的数据 TreeSelect 树形选择 在原demo基础上修改 const chineseNumber 一二三四五六七八九十.…

音视频入门基础:FLV专题(9)——Script Tag简介

一、SCRIPTDATA 根据《video_file_format_spec_v10_1.pdf》第75页到76页&#xff0c;如果某个Tag的Tag header中的TagType值为18&#xff0c;表示该Tag为Script Tag&#xff08;脚本Tag&#xff0c;又称Data Tag、SCRIPTDATA tag&#xff09;。这时如果Filter的值不为1表示未加…

昇思MindSpore进阶教程--使能图算融合

大家好&#xff0c;我是刘明&#xff0c;明志科技创始人&#xff0c;华为昇思MindSpore布道师。 技术上主攻前端开发、鸿蒙开发和AI算法研究。 努力为大家带来持续的技术分享&#xff0c;如果你也喜欢我的文章&#xff0c;就点个关注吧 正文开始 图算融合是MindSpore特有的网络…

十二生肖国庆姓氏专属头像

关注▲洋洋科创星球▲领取十二生肖国庆姓氏专属头像定制&#xff01; 庆祝祖国75周年华诞&#xff0c;在这个举国欢庆的国庆节时刻&#xff0c;我们特别为您准备了一份独特的礼物——十二生肖国庆姓氏专属头像定制。 十二生肖&#xff0c;又称属相&#xff0c;是中国传统文化中…

Linux 安装redis主从模式+哨兵模式3台节点

下载 https://download.redis.io/releases/ 解压 tar -zxvf redis-7.2.4.tar.gz -C /opt chmod 777 -R /opt/redis-7.2.4/安装 # 编译 make # 安装&#xff0c; 一定是大写PREFIX make PREFIX/opt/redis-7.2.4/redis/ install配置为系统服务 cd /etc/systemd/system/主服务…

盒子是什么? -- 第四课

文章目录 前言一、盒子是什么&#xff1f;二、元素介绍1.边框 - border2.内边距 - padding3. 外边距属性 -- margin 三、拓展知识1.块元素垂直外边距的合并2. 嵌套块元素垂直外边距的合并 四、背景属性五、元素的浮动1.浮动2.清除浮动3.元素定位4. 特殊定位 -- 黏性定位5. z-in…