Qt线程同步的几种方法

Qt 多线程的几种实现方式 Qt多线程的实现方式有: 1. 继承QThread类,重写run()方法 2. 使用moveToThread将一个继承QObject的子类移至线程,内部槽函数均在线程中执行 3. 使用QThreadPool,搭配QRunnable(线程池) 4. 使用QtConcurrent(线程池) 阅读详情
AI摘要

本文详细介绍了Qt中的多种并发编程机制,包括QMutex、QMutexLocker、QReadWriteLock、QReadLocker/QWriteLocker、QSemaphore及QWaitCondition等,并探讨了它们在实际场景中的应用。

一、QMutex类

       QMutex类就像一把锁,在互斥量之前上锁(QMutex::lock()),然后在使用完互斥量之后解锁(QMutex::unlock())。比如下面的代码:

void someMethod()
{
    mutex.lock();
    qDebug()<<"Hello";
    qDebug()<<"World";
    mutex.unlock();
}
 
class Thread1 : public QThread  
{
protected:
    virtual void run()
    {
        someMethod();
    }
};
 
class Thread2 : public QThread  
{
protected:
    virtual void run()
    {
        someMethod();
    }
};

如上面的代码,在函数someMethod里面有两条语句,如果有两个线程启动之后,这两个线程都将调用这个函数(run函数即为线程启动后自动执行的函数),则可能会出现的结果是Hello Hello World World。但显然,这并不是我们想要的,我们希望的是每个线程可以一次性执行完someMethod函数里面的代码。这个时候我们便可以在函数里面给函数体加上锁,然后在结束的时候解锁。

这里需要注意的是,如果一个线程试图向一个已经被其它线程上锁了互斥量上锁的话,这个线程将被阻塞(挂起),直到这个互斥量被解锁。如果一个线程希望自己在试图对一个上锁了的互斥量进行访问的时候能够不被阻塞(而是立即返回),可以将lock()函数替换为tryLock()函数,这个函数的效果是:如果线程正在试图访问的互斥量已经被上锁了,那么可以立即返回而不被阻塞。

二、QMutexLocker便利类

使用 QMutex 对互斥量进行加锁解锁比较繁琐,在一些复杂的函数或者抛出C++异常的函数中都非常容易发生错误。可以使用一个方便的 QMutexLocker 类来简化对互斥量的处理。首先,QMutexLocker类的构造函数接收一个QMutex对象作为参数并且上锁,然后在析构函数中自动对其进行解锁。如下代码:


QMutex mutex;
 
void someMethod()
{
    QMutexLocker locker(&mutex);
    qDebug()<<"Hello";
    qDebug()<<"World";
}

这里创建一个QMutexLocker类实例,在这个实例的构造函数中将对mutex对象进行加锁。然后在析构函数中自动对mutex进行解锁。解锁的工作不需要显示地调用unlock函数,而是根据QMutexLocker对象的作用域绑定在一起了。

三、QReadWriteLock类

      前两种保护互斥量的方法比较绝对,其达到的效果是:不管我要对互斥量做些是什么,我都要一个人霸占着,即使我只是看看它,也不能让别人看。这会使得这个互斥量资源的使用率大大下降,造成资源等待等问题。

      于是,我们可以对线程对互斥量的操作进行分类:读和写。有几种情况:

1、如果我只是看看的话,你也可以看,大家看到的都是正确的结果;

2、如果我要看这个数据,你是不能改的,不然我看到的结果就不知道是什么了;

3、我在改的时候,你不能看,否则我可能会让你看到不正确的结果;

4、我在改的时候,你当然不能改了。

因此,我们可以对QMutex锁进行升级,将其升级为QReadWriteLock,QMutex加锁的方法是lock(),而QReadWriteLock锁有两种锁法:设置为读锁(lockForRead())和写锁(lockForWrite())。代码如下:

QReadWriteLock lock;
void someMethod()
{
lock.lockForRead(); //为读而锁
//lock.lockForWrite(); //为写而锁
qDebug()<<"Hello";
qDebug()<<"World";

lock.unlock();  //解锁
}

于是可能有以下四种情况:

1、一个线程试图对一个加了读锁的互斥量进行上读锁,允许;

2、一个线程试图对一个加了读锁的互斥量进行上写锁,阻塞;

3、一个线程试图对一个加了写锁的互斥量进行上读锁,阻塞;

4、一个线程试图对一个加了写锁的互斥量进行上写锁,阻塞。

所以可以看出,读写锁比较适用的情况是:需要多次对共享的数据进行读操作的阅读线程。

四、QReadLocker便利类和QWriteLocker便利类对QReadWriteLock进行加解锁

和QMutex与QMutexLocker类的关系类似,关于读写锁也有两个便利类,读锁和写锁,QReadLocker和QWriteLocker。它们的构造函数都是一个QReadWriteLock对象,不同的是,在QReadLocker的构造函数里面是对读写锁进行lockForRead()加锁操作,而在QWriteLocker的构造函数里面是对读写锁进行lockForWrite()加锁操作。然后解锁操作unlock()都是在析构函数中完成的。

void write()
{
QReadLocker locker(&lock);
..........
}

void read()
{
QWriteLocker locker(&lock);
..............
}

QReadLocker和QWriteLocker的成员函数都一模一样,退出函数的时局部变量locker会自动销毁,讲lock自动解锁。也可以调用locker.unlock()给lock解锁,然后再调用locker.relock()再锁住lock。也可以调用locker.readWriteLock()获取建立locker时引入的那个lock的指针。

五、信号量QSemaphore

前面的几种锁都是用来保护只有一个变量的互斥量的。但是还有些互斥量(资源)的数量并不止一个,比如一个电脑安装了2个打印机,我已经申请了一个,但是我不能霸占这两个,你来访问的时候如果发现还有空闲的仍然可以申请到的。于是这个互斥量可以分为两部分,已使用和未使用。一个线程在申请的时候,会对未使用到的部分进行加锁操作,如果加锁失败则阻塞,如果加锁成功,即又有一个资源被使用了,于是则将已使用到的部分解锁一个。

以著名的生产者消费者问题为例,分析问题:生产者需要的是空闲位置存放产品,结果是可取的产品多了一个。于是,我们可以定义两个信号量:QSemaphore freeSpace和QSemaphore usedSpace,前者是给生产者使用的,后者是给消费者使用的。

 

六、条件触发QWaitCondition

QWaitCondition最大的好处,我觉得,是能在一个线程中唤醒一个或多个其它线程,当然前提是,其它线程在等待某个QWaitCondition,否则不起作用,你唤醒也没用。QWaitCondition必须与QMutex或者QReadwriteLock一起用。

 

原文链接:https://blog.youkuaiyun.com/hulifangjiayou/article/details/47018895

https://blog.youkuaiyun.com/michealtx/article/details/6853604

 

Qt同步线程的几种方法 一、QMutex类 QMutex类就像一把锁,在互斥量之前上锁(QMutex::lock()),然后在使用完互斥量之后解锁(QMutex::unlock())。比如下面的代码: void someMethod() { mutex.lock(); qDebug()<<"Hello"; qDebug()<<"World"; mutex.unlock(); } 阅读详情

相关推荐

QT线程同步与异步处理

QT多线程专栏共有14篇文章,从初识线程到、QMutex锁、QSemaphore信号量、Emit、Sgnals、Slot主线程子线程互相传值同步变量、QWaitCondition、事件循环、QObjects、线程安全、线程同步、线程异步、QThreadPool线程池等线程操作进行了全面!深入!的研究和详细的说明

断点 6371

Qt高级系列之8:Qt多线程线程池数据同步机制及文件下载器项目实战

1.带领您深入学习QT5/C++:Qt多线程线程池及数据同步机制 ,多线程文件下载器项目实战,继承自QThread,继承自QObject,QRunnable和QThreadPool,QtConcurrent,Qt多线程技术与数据加锁保护机制:QMutex,QSemaphore,QReadWriteLock,QWaitCondition;Qt线程池技术、Qt数据库连接池、等。2.所有章节均有理论知识介绍、接口讲解、实例代码讲解,讲解过程中不断穿插老师在开发过程中遇到的问题及解决方法(可以下载所有的电子课件与源码)。

Qt中的多线程同步

本文将介绍几种常用的线程同步技术,并提供相应的源代码示例。读写锁是一种特殊的锁,用于在读多写少的情况下提高并发性能。需要注意的是,在使用这些线程同步机制时,我们需要谨慎地处理锁的获取和释放,以免出现死锁或其他线程同步问题。此外,合理地设计线程间的通信和同步策略,可以提高程序的性能和可维护性。互斥锁是一种最基本的线程同步机制,它用于保护共享资源,使得同一时间只有一个线程可以访问该资源。通过使用互斥锁、读写锁和条件变量,我们可以实现在Qt中的线程同步和数据共享。发出条件满足的信号,唤醒等待的线程。

DevAstro的博客 359

常用Qt线程同步的几种方法

一、QMutex类 QMutex类就像一把锁,在互斥量之前上锁(QMutex::lock()),然后在使用完互斥量之后解锁(QMutex::unlock())。比如下面的代码: void someMethod() { mutex.lock(); qDebug()<<"Hello"; qDebug()<<"World"; mutex.unlock(); } class Thread1...

肖邦的夜曲的专栏 1089

Qt中的线程同步

在Qt中,线程同步是一种重要的技术,用于确保多个线程之间的正确交互和共享资源的安全访问。线程同步的目标是避免竞态条件(Race Condition)和其他线程相关的问题,以确保程序的正确性和可靠性。通过使用互斥锁、信号量和条件变量等线程同步机制,Qt提供了强大而灵活的工具来确保多线程程序的正确性和可靠性。它通过保护共享资源,一次只允许一个线程访问该资源,从而避免多个线程对同一资源的并发访问。信号量是一种更高级的线程同步机制,它可以限制对共享资源的并发访问数量。在上面的示例中,通过使用一个计数为1的。

ByteBuster的博客 181

Qt—页面加载和数据同步

本文主要介绍界面显示和数据处理同步方式

zhangchuan7758的博客 1710

QT多线程同步之QWaitcondition

使用到多线程,无可避免的会遇到同步问题,qt提供几种同步线程的方法,在这里讲一下QWaitcondition的简单使用。 一、QWaitcondition,是通过一个线程达到某种条件来唤起另一个线程来实现同步的 mutex.lock(); waitcondition.wait(&mutex); 需要用到一个互斥量作为参数,而这个互斥量的状态必须是locked的。 当调用...

banyuejun8353的博客 963

Qt/C++音视频开发24-ffmpeg音视频同步

一、前言 用ffmpeg来做音视频同步,个人认为这个是ffmpeg基础处理中最难的一个,无数人就卡在这里,怎么也不准,本人也是尝试过网上各种demo,基本上都是渣渣,要么仅仅支持极其少量的视频文件比如收到的数据包是一帧视频一帧音频的,要么根本没法同步歪七八糟的,要么进度跳过去直接蹦蹦蹦崩溃的,其实最完美的音视频同步处理demo就是ffplay,我亲测过几十种各种各样的音视频本地文件,数十种视频流文件,都是非常完美,当然啦这是亲生的啦,不完美还玩个屁。 如果仅仅是播放视频流(不带音频流),可能不需要音视频同步

Qt/C++视频监控/推流/物联网/大屏系统/自定义控件/UI定制/输入法 3128

C++ GUI QT 第4版 之线程(二) 线程的同步

QT中提供了一下几个可以实现线程同步的类:

linlinmaqiong的专栏 483

Seurat 单细胞转录组测序数据分析教程(三)——python(scanpy)

文章参考至,做了一个更详细的解读。本教程探讨了 scanpy 的可视化可能性,分为三个部分:嵌入的散点图(例如 UMAP、t-SNE)使用已知标记基因鉴定簇差异表达基因的可视化在本教程中,我们将使用来自 10x 的数据集,其中包含来自PBMC的 68k 个细胞。Scanpy 在其分布中包括该数据集的简化样本,该数据集仅包含 700 个细胞和 765 个高度可变的基因。该数据集已经过预处理和 UMAP 计算。在本教程中,我们还将使用以下文献标记:B细胞:CD79A、MS4A1。

coffeeii的博客 5827

VSCode+Keil高效开发STM32:Keil Assistant插件配置全攻略

本文详细介绍了如何通过VSCode的Keil Assistant插件,将Keil MDK的编译调试能力与VSCode的现代编辑体验相结合,打造高效的STM32开发环境。文章涵盖了从环境配置、工程导入、智能提示设置到与STM32CubeMX协同工作的全流程攻略,旨在解决Keil编辑器效率低下的痛点,大幅提升嵌入式开发的编码与项目管理效率。

gold的博客 507

qt 创建线程的方式有几种

qt 创建线程的方式有几种

xie__jin__cheng的博客 1165

ros_control硬件接口实战:从零构建机器人控制框架

本文详细介绍了ros_control硬件接口在机器人控制框架中的核心作用与实践方法。通过解析硬件接口类型、实现标准接口、构建主控制循环及自定义功能扩展,帮助开发者从零构建高效的机器人控制系统,提升硬件与ROS的协同效率。

lstm7chronicler的博客 500

C++ GUI QT 第4版 之线程(二) 线程的同步(1)

QT中提供了一下几个可以实现线程同步的类: (1)QMutex 类  QMutex  mutex定义一个互斥信号量,目的是保护对象,数据结构或代码段   步骤:    mutex.lock();加锁    临近资源,代码的处理    mutex.unlock();解锁 QMutex提供了线程间的顺序访问。 QMutex的目的是保护

默默的努力 830

【车间调度】车间调度问题的分类

本系列为自己学习调度相关知识的记录,如有误请指出,也欢迎调度方向的小伙伴加我好友共同交流。 车间调度问题的分类 根据工件和车间构成不同,车间调度问题可分为以下几种 1.单机调度问题 在单机调度问题(S,SMP)中,加工系统只有一台机床,待加工的工件有且仅有一道工序,所有工件都在该机床上进行加工。此问题是最简单的调度问题,当生产车间出现瓶颈机床时的调度就可视为此调度问题。 ...

weixin_51656605的博客 7429

接入 deepseek 实现AI智能问诊

必须包含user角色,用于传递用户输入。system角色可选,用于设置对话背景。多轮对话需要将历史记录添加到messages中。

weixin_51326478的博客 6541

QT 线程相关

信号和槽:通过信号通知任务完成。QFuture和:提供更灵活的异步任务管理,可以获取任务的返回值。:等待线程池中的所有任务完成,但会阻塞当前线程。根据你的需求选择合适的方法。如果你需要任务的返回值,建议使用和QFuture。

轩辕霸天L 699

AUTOSAR OS Counter讲解

Counter(计数器)以tick为单位记录操作系统中发生了多少“事情”。tick(滴答)是一个抽象的单位。时间,例如毫秒,微妙,分钟等,然后计数器计算过去了多少时间旋转,例如以度或分钟为单位,计数器计算物体旋转了多少按钮按下,计数器计算按钮按下多少次错误,计数器计算错误发生的频次中断(有时是任务)用于驱动一个计数器。该驱动程序负责进行正确的OS API调用来滴答计数器,或者告诉OS计数器已经滴答到一个所需的值。

酒无忧的博客 1070

QT-线程同步

分类: QT2011-04-04 14:23 7816人阅读 评论(0) 收藏 举报 qt产品多线程thread数据结构file 线程互斥        多线程运行时,通常会访问同一个变量,同一个数据结构,或者同一段代码。因此,需要使用互斥技术来保护上述资源,确保多线程执行的正确性。 注: 我们通常说某个函数是线程安全的,也就是因为该函数实现加入了线程互斥保护。        

xingzheouc的专栏 315

【AI智能体】Codex + Seedance2.5 制作AI视频实战操作详解

【AI智能体】Codex + Seedance2.5 制作AI视频实战操作详解

congge_study的博客 3793

基于STM32L4XX、HAL库的TESEO-LIV4FTR定位模块驱动程序设计

支持多星座系统:GPS、GLONASS、Galileo和北斗。支持NMEA 0183协议和ST专有协议。高灵敏度:-167dBm跟踪灵敏度。低功耗设计,适合物联网和便携设备。内置LNA和SAW滤波器。

zhusl6688的博客 237

解析Qt中QThread使用方法

解析Qt中QThread使用方法 本文介绍了Qt中QThread使用方法,在本片文章中反复提到了线程的使用,详细内容请参考本文,QThread的使用方法:#include 继承了Qt。 AD:2014WOT全球软件技术峰会北京站课程视频发布 本文讲述的是在Qt中QThread使用方法,QThread似乎是很难的一个东西,特别是信号和槽,有非常多的人(尽管使用者本人往往不知道)在用不恰当(

u011493488的专栏 1163

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

Qt多线程同步与通信

1 多线程同步 Qt提供了以下几个类来完成这一点:QMutex、QMutexLocker、QSemphore、QWaitCondition。 当然可能还包含QReadWriteLocker、QReadLocker、QWriteLocker,但线程同步是应用很少,这里只做简单的讲解! QMutex、QMutexLocker QMutex类提供了一个保护一段临界区代码的方法,他每次只允许一个线程访问这...

qq_35718950的博客 500

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

在Qt项目中使用QtConcurrent::run,实现异步等待和同步调用

Qt 使用QtConcurrent::run实现C#中类似async await 的用法

ocean 328

STM32F407中文手册

STM32f407中文手册 本参考手册面向应用开发人员,提供有关使用 STM32F405xx/07xx、STM32F415xx/17xx、 STM32F42xxx 和 STM32F43xxx 微控制器存储器与外设的完整信息。STM32F405xx/07xx、STM32F415xx/17xx、STM32F42xxx 和 STM32F43xxx 构成一个微 控制器系列,各产品具有不同的存储器大小、封装和外设。有关订购信息以及器件的机械与电气特性,请参见数据手册。有关 ARM Cortex™-M4F 内核的信息,请参见《Cortex™-M4F 技术参考手册》。

Qt 线程同步的方式及数量详解

Qt 线程同步的方式及数量详解

xie__jin__cheng的博客 965
上一篇: C++线程同步的四种方式(Windows)
下一篇: chrome 安装 gliffy 绘图插件以及使用
e5Max
博客等级 码龄14年 145粉丝 129原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值