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

Qt-系统线程安全(63)

目录

描述

使用

线程不安全

线程安全

释放锁问题

其他的锁

条件变量和信号量


描述

多线程程序太复杂了

在C/C++ 和 Linux中,我们为了保证线程安全,简单的方式就是加锁

 

为此 Qt  也封装了自己的一套锁管理

使用

线程不安全

我们先测验一下线程不安全的情况,先自定义一个类,等会要重写 QThread 类

thread.h 

thread.cpp

一个简单的累加 

运行发现,结果并不是我们所想象中的那样

线程安全

对++ 进行加锁,在CPU指令之中,++操作一共有三个指令,本身不是原子的,所以有线程不安全的问题,我们对涉及到修改的代码块进行加锁,保证线程安全

创建一共静态的锁对象,确保是使用同一把锁

运行正常,累加到了应有的数值 

 

释放锁问题

关于锁的释放,是有可能忘记释放的,忘记 unlock

在临界区之中,由于可能存在 判断,异常之类的操作,可能会导致锁没有释放

 

在C++释放内存中也有这样的问题存在,因此C++ 引入了智能指针,来解决内存释放和锁释放的问题

在出花括号区域的时候,lock_guard会自动调用析构,来释放 锁 

 

Qt 为了锁的释放也参考了这种做法,创建了 mutexLocker

使用如下,和C++之中的 std::lock_guard 使用方式一样

不建议和C++混着用锁相关函数

其他的锁

Qt中还有很多其他的锁,诸如读写锁,在特定的场景有着很好的发挥

QReadWriteLocker、QReadLocker、QWriteLocker

QReadWriteLock 是读写锁类,⽤于控制读和写的并发访问。
QReadLocker ⽤于读操作上锁,允许多个线程同时读取共享资源。
QWriteLocker ⽤于写操作上锁,只允许⼀个线程写⼊共享资源。

条件变量和信号量

条件变量

        在多线程编程中,假设除了等待操作系统正在执⾏的线程之外,某个线程还必须等待某些条件满⾜才能执⾏,这时就会出现问题。这种情况下,线程会很⾃然地使⽤锁的机制来阻塞其他线程,因为这只是线程的轮流使⽤,并且该线程等待某些特定条件,⼈们会认为需要等待条件的线程,在释放互斥锁或读写锁之后进⼊了睡眠状态,这样其他线程就可以继续运⾏。当条件满⾜时,等待条件的线程将被另⼀个线程唤醒。
在 Qt 中,专⻔提供了 QWaitCondition类 来解决像上述这样的问题。
        特点:QWaitCondition 是 Qt 框架提供的条件变量类,⽤于线程之间的消息通信和同步。
        ⽤途:在某个条件满⾜时等待或唤醒线程,⽤于线程的同步和协调

伪代码如下,使用过程也大致如下 

QMutex mutex;
QWaitCondition condition;
//在等待线程中
mutex.lock();
//检查条件是否满⾜,若不满⾜则等待
while (!conditionFullfilled())
{
condition.wait(&mutex); //等待条件满⾜并释放锁
}
//条件满⾜后继续执⾏
//...
mutex.unlock();
//在改变条件的线程中
mutex.lock();
//改变条件
changeCondition();
condition.wakeAll(); //唤醒等待的线程
mutex.unlock();

信号量

        有时在多线程编程中,需要确保多个线程可以相应的访问⼀个数量有限的相同资源。例如,运⾏程序的设备可能是⾮常有限的内存,因此我们更希望需要⼤量内存的线程将这⼀事实考虑在内,并根据可⽤的内存数量进⾏相关操作,多线程编程中类似问题通常⽤信号量来处理。信号量类似于增强的互斥锁,不仅能完成上锁和解锁操作,⽽且可以跟踪可⽤资源的数量。
        特点:QSemaphore 是 Qt 框架提供的计数信号量类,⽤于控制同时访问共享资源的线程数量。
        ⽤途:限制并发线程数量,⽤于解决⼀些资源有限的问题

伪代码,使用过程如下 

QSemaphore semaphore(2); //同时允许两个线程访问共享资源
//在需要访问共享资源的线程中
semaphore.acquire(); //尝试获取信号量,若已满则阻塞
//访问共享资源
//...
semaphore.release(); //释放信号量
//在另⼀个线程中进⾏类似操作


http://www.kler.cn/a/350449.html

相关文章:

  • Web前端开发技术之HTMLCSS知识点总结
  • 第15章:Python TDD应对货币类开发变化(二)
  • IJCAI-2024 | 具身导航的花样Prompts!VLN-MP:利用多模态Prompts增强视觉语言导航能力
  • tui-editor报错
  • 与专业舆情优化公司合作是品牌化解舆情危机的重要途径
  • RabbitMQ-消息可靠性以及延迟消息
  • 【系统架构设计师】案例专题二:系统开发基础考点梳理
  • Python 如何使用 Bert 进行中文情感分析
  • Linux网络命令:用于管理和显示网络路由表的工具route详解
  • KAN论文
  • PCL滤波器之面试总结
  • linux----cd和pwd命令
  • 基于yolov5的手机屏幕缺陷检测系统,支持图像、视频和摄像实时检测【pytorch框架、python源码】
  • 前端vue-获取验证码和重新获取验证码倒计时
  • 【数据结构】栈和队列 + 经典算法题
  • C语言 编程练习:解决五个有趣的问题
  • Lumerical学习——分析工具(Analysis tools)
  • 0047__【python打包分发工具】setuptools详解
  • Gin框架操作指南10:服务器与高级功能
  • 移情别恋c++ ദ്ദി˶ー̀֊ー́ ) ——6.vector(无习题)
  • React native之全局变量存储AsyncStorage
  • linux 环境运行 jenkins.war包,有可能会出现字体问题,jdk版本:11 jenkins 版本:2.420
  • 数据结构常考基础代码题-顺序表有序插入
  • JAVA基础(6)
  • 【开源风云】从若依系列脚手架汲取编程之道(五)
  • 单片机死机后在不破坏现场的情况下连接调试器进入调试模式