Qt的互斥量用法

embedded/2024/10/18 10:26:17/

目的

互斥量的概念

互斥量是一个可以处于两态之一的变量:解锁和加锁。这样,只需要一个二进制位表示它,不过实际上,常常使用一个整型量,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.ppmy.cn/embedded/124242.html

相关文章

dockertop提示Failed to fetch extensions

解决办法&#xff1a;重装dockertop 第一步&#xff1a;卸载当前的dockertop 如果卸载过程中存在AlibabaProtect的相关软件关不掉&#xff0c;那么参考这篇文章&#xff1a;卸载AlibabaProtect 第二步&#xff1a;删除C:\Program Files路径下的Docker文件夹 第三步&#xff1…

大数据毕设方向怎么做

文章目录 &#x1f6a9; 1 前言1.1 选题注意事项1.1.1 难度怎么把控&#xff1f;1.1.2 题目名称怎么取&#xff1f; 1.2 开题选题推荐1.2.1 起因1.2.2 核心- 如何避坑(重中之重)1.2.3 怎么办呢&#xff1f; &#x1f6a9;2 选题概览&#x1f6a9; 3 项目概览题目1 : 基于协同过…

JavaScript 与 HTML 的结合

在 HTML 页面中嵌入 JavaScript 代码是实现动态效果和交互功能的关键一步。下面是一些常用的方法来实现 JavaScript 与 HTML 的结合。 内联方式&#xff1a;可以直接在 HTML 元素的事件属性中嵌入 JavaScript 代码。例如&#xff0c;可以在按钮的 onclick 属性中添加 JavaScri…

INS风格时尚自拍人像摄影后期Lr调色,手机滤镜PS+Lightroom预设下载!

调色教程 INS 风格时尚自拍人像摄影后期通过 Lightroom&#xff08;Lr&#xff09;调色&#xff0c;打造出具有高质感、时尚感和个性魅力的人像照片。这种风格深受社交媒体用户的喜爱&#xff0c;能够让自拍人像在众多照片中脱颖而出。 预设信息 调色风格&#xff1a;INS风格…

算法打卡:第十一章 图论part11

今日收获&#xff1a;Floyd 算法&#xff0c;A * 算法&#xff0c;最短路算法总结 1. Floyd 算法 题目链接&#xff1a;97. 小明逛公园 思路&#xff1a;Floyd用于解决多源最短路问题&#xff0c;对边的正负权值没有要求。核心是动态规划 &#xff08;1&#xff09;dp数组的…

AJAX 1——axios体验、认识URL、常用请求方法、HTTP协议、错误处理、form-serialize插件

AJAX 1——axios体验、认识URL、常用请求方法、HTTP协议、错误处理、form-serialize插件 1.AJAX入门与体验axios 定义&#xff1a;浏览器与服务器进行数据通信的技术 体验axios库&#xff0c;与服务器通信 引入axios.js使用axios函数 <p class"my-p"></p&…

Elasticsearch基础_4.ES搜索功能

文章目录 一、搜索辅助功能1.1、指定返回的字段1.2、结果计数1.3、结果分页 二、搜索匹配功能2.1、查询所有文档2.2、term级别查询2.2.1、term查询2.2.2、terms查询2.2.3、range查询2.2.4、exists查询 2.3、布尔查询2.3.1、must&#xff0c;should&#xff0c;must_not2.3.2、f…

动手学深度学习(李沐)PyTorch 第 7 章 现代卷积神经网络

7.1 深度卷积神经网络&#xff08;AlexNet&#xff09; 在计算机视觉中&#xff0c;直接将神经网络与其他机器学习方法进行比较也许不公平。这是因为&#xff0c;卷积神经网络的输入是由原始像素值或是经过简单预处理&#xff08;例如居中、缩放&#xff09;的像素值组成的。但…