QT QMutex 使用详解

举报
华为云 断点 发表于 2022/12/06 01:47:48 2022/12/06
【摘要】 QT多线程编程系列专栏文章共有12篇,全面的讲述、实现、运行了QT多线程的各种操作,包括运行原理、线程、进程、多线程、锁、QMutex、QSemaphore、 Emit、Sgnals、Slot、QWaitCondition、线程事件循环、QObjects、重入与线程安全、主线程子线程互相传值、线程同步与异步处理、线程的使用、浅拷贝、深拷贝、隐式共享、隐式共享机制对STL样式迭代器的影响等等文章。

    QT多线程编程系列专栏文章共有12篇,全面的讲述、实现、运行了QT多线程的各种操作,包括运行原理、线程、进程、多线程、锁、QMutex、QSemaphore、 Emit、Sgnals、Slot、QWaitCondition、线程事件循环、QObjects、重入与线程安全、主线程子线程互相传值、线程同步与异步处理、线程的使用、浅拷贝、深拷贝、隐式共享、隐式共享机制对STL样式迭代器的影响等等文章。

本文作者原创首发于CSDN,本文原创请勿转载

版权声明:本文为CSDN博主「双子座断点」的原创文章,遵循CC 4.0 BY-SA版权协议。
原文链接:https://blog.csdn.net/qq_37529913/article/details/110127940

    QMutex类提供的是线程之间的访问顺序化。QMutex的目的是保护一个对象、数据结构或者代码段,所以同一时间只有一个线程可以访问它。

      例如,这里有一个方法打印给用户两条消息:

          void DebugInfo()
          {
             qDebug("ABC");
             qDebug("DEF");
          }

如果同时在两个线程中调用这个方法,结果的顺序将是:

ABC ABC DEF DEF

如果你使用了一个互斥量:

    QMutex mutex;
     
      void DebugInfo()
      {
         mutex.lock();
         qDebug("ABC");
         qDebug("DEF");
         mutex.unlock();
      }

如果同时在两个线程中调用这个方法,结果的顺序将是:

ABC DEF ABC DEF

如果使用Mutex锁那么多个线程在访问一段代码的时候是存在阻塞的,一个执行完毕下一个线程才会继续执行。

如果不加锁的话因为多个线程你抢一下我抢以下就会出现ABC ABC DEF DEF情况

下面是复制粘贴过来的可以看看,也可以忽略。但是locked ()  tryLock () unlock() 三种锁的函数还是建议了解一下。

然后同一时间只有一个线程可以运行DebugInfo()并且消息的顺序也一直是正确的。当然,这只是一个很简单的例子,但是它适用于任何需要按特定频率发生的情况。
但你在一个线程中调用lock(),其它线程将会在同一地点试图调用lock()来阻塞,知道这个线程调用unlock()之后其它线程才会获得这个锁。lock()的一种非阻塞选择是tryLock()。

只有一个锁,只能被一个QMutex得到,如果QMutex得不到这个锁,那它将不会执行紧随其后的代码,也就是在两个进程代码中需要共用一个QMutex类的实例,这样才能保证该实例是否获取到一个锁或者得不到一个锁。

如果QMutex::lock()得不到这个锁,那么它将会一直等直到得到该锁为止,而另一个方法QMutex::tryLock()可以检测当前是否可以得到这个锁,如果可以得到则返回1,否则返回0(不会一直等,但如果可以得到锁,那就拿到锁,不会光判断而不获取锁),该函数只执行一次,不会一直等到得到锁为止。

成员函数:
QMutex::QMutex ( bool recursive = FALSE )
构造一个新的互斥量。这个互斥量是在没有锁定的状态下创建的。如果recursive为真,就构造一个递归互斥量,如果recursive为假(默认值),就构造一个普通互斥量。对于一个递归互斥量,一个线程可以锁定一个互斥量多次并且只有在相同数量的unlock()调用之后,它才会被解锁。
QMutex::~QMutex () [虚]
销毁这个互斥量。
void QMutex::lock ()
试图锁定互斥量。如果另一个线程已经锁定这个互斥量,那么这次调用将阻塞直到那个线程把它解锁。
也可以参考unlock()和locked()。
bool QMutex::locked ()
如果互斥量被另一个线程锁定了,返回真,否则返回假。
警告:由于不同平台上递归互斥量的实现不同,所以从以前锁定这个互斥量的同一个线程上调用这个函数可能会返回未定义的结果。
也可以参考lock()和unlock()。
bool QMutex::tryLock ()
试图锁定互斥量。如果锁被得到,这个函数返回真。如果另一个进程已经锁定了这个互斥量,这个函数返回假,而不是一直等到这个锁可用为止,比如,它不是阻塞的。
在另一个线程可以成功锁定它之前,这个锁必须被调用unlock()来解锁。
也可以参考lock()、unlock()和locked()。
void QMutex::unlock ()
解锁这个互斥量。试图对不同的线程中锁定的互斥量进行解锁将会返回一个错误。对一个没有锁定的互斥量进行解锁的结果是将导致未定义的行为(不同的操作系统的线程实现是有很大不同的)。
也可以参考lock()和locked()。

借鉴参考文章:QMutex使用详解_Geek.Fan的博客-CSDN博客_qmutex

借鉴参考文章:【Qt 5】Qt中QMutex的一点理解_墨小鱼的博客-CSDN博客_qt qmutex

【版权声明】本文为华为云社区用户原创内容,未经允许不得转载,如需转载请自行联系原作者进行授权。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。