关于Qt中的QMutex——关于lock与unlock
大概说一下用法,例子:
QMutex mutex;
int number = 6;
void method1()
{
mutex.lock();
number *= 5;
number /= 4;
mutex.unlock();
}
void method2()
{
mutex.lock();
number *= 3;
number /= 2;
mutex.unlock();
}
用法大概可以总结为这样:
QMutex mutex;
void method() {
mutex.lock();
// 你要做的骚操作
mutex.unlock()
}
作用:确保同一时间只有一个线程可以运行lock与unlock之间的内容。
其实这就是一个互斥锁,经常用的地方是在访问资源并作出修改的时候。这时候我们不希望有别的线程来同时访问同一个资源,所以会给两个线程要访问资源的地方的代码加上互斥锁,这样只有一个线程访问完资源处理完并unlock后,另一个线程才可以继续执行。所以可以看到,QMutex的lock其实是阻塞式的,如果不能够取得锁那么没有办法继续往下执行。如果想要弄成非阻塞式的,那么就要用tryLock,并设置超时时长。但是这个就不展开说了。
例如,同时访问一个全局变量number:
int number = 6;
void method1()
{
number *= 5;
number /= 4;
}
void method2()
{
number *= 3;
number /= 2;
}
method1和method2分别是由两个线程运行,正常情况下,我们的执行顺序应该是这样的:
// method1()
number *= 5; // number is now 30
number /= 4; // number is now 7
// method2()
number *= 3; // number is now 21
number /= 2; // number is now 10
调用顺序不影响结果。
如果不加上互斥锁,那么可能执行的顺序是:
// Thread 1 calls method1()
number *= 5; // number is now 30
// Thread 2 calls method2().
//
// Most likely Thread 1 has been put to sleep by the operating
// system to allow Thread 2 to run.
number *= 3; // number is now 90
number /= 2; // number is now 45
// Thread 1 finishes executing.
number /= 4; // number is now 11, instead of 10
所以我们需要加上互斥锁,确保当前只有一个进程访问变量number(可以看作是资源,其实原理都差不多):
QMutex mutex;
int number = 6;
void method1()
{
mutex.lock();
number *= 5;
number /= 4;
mutex.unlock();
}
void method2()
{
mutex.lock();
number *= 3;
number /= 2;
mutex.unlock();
}
这样就可以确保只有一个线程完成了任务之后并且释放掉互斥锁之后,另一个线程才开始运行,保证了线程的完整运行和正确结果。
此外,可以通过成员函数bool QMutex::locked ()来确定一个互斥量有没有被lock。如果已经被锁定了返回true,否则返回false。
参考
关于Qt中的QMutex——关于lock与unlock的更多相关文章
- Qt中sleep()的实现(耳目一新的两种方法)
在Qt中并没有Sleep函数可以调用,在程序编写时往往需要休眠几秒,这里举出两个方法,不知道是否啥不良隐患没~~ 方法一: class SleeperThread : public QThread{p ...
- Qt入门(9)——Qt中的线程支持
Qt对线程提供了支持,基本形式有独立于平台的线程类.线程安全方式的事件传递和一个全局Qt库互斥量允许你可以从不同的线程调用Qt方法.警告:所有的GUI类(比如,QWidget和它的子类),操作系统核心 ...
- Qt中暂停线程的执行(主线程和工作线程共用一把锁,一旦主线程将它锁上,工作线程就无法运行了,这也是一个办法)
在线程中定义一个信号量: QMutex pause; 把run()函数中循环执行的部分用信号量pause锁住: void run() { while(1) { pause.lock ...
- 解析Qt中QThread使用方法
本文讲述的是在Qt中QThread使用方法,QThread似乎是很难的一个东西,特别是信号和槽,有非常多的人(尽管使用者本人往往不知道)在用不恰当(甚至错误)的方式在使用QThread,随便用goog ...
- qt中线程的使用方法
QT中使用线程可以提高工作效率. 要使用线程要经过一下四个步骤: (1)先创建一个c++ class文件,记得继承Thread,创建步骤如下: a.第一步 b.第二步 (2)自定义一个run函数,以后 ...
- Qt中(图片)资源的使用方式
Qt中使用图片资源的方法有很多种,以前我一直分不清各种之间的区别和Qt相应的处理机制,后来遇到一些实际的问题,然后再加上查阅源码和资料,总算弄明白一些事情,但是本文仅仅是个人理解,如有错误之处请告诉我 ...
- QT中实现应用程序的单例化
一介绍 通过编写一个QSingleApplication类,来实现Qt程序的单例化,原文的作者是在Windows Vista + Qt4.4 下实现的,不过应用在其他平台上是没问题的.(本文是我在ht ...
- 用事件队列解决GUI的操作顺序问题(Qt中处理方法)
GUI操作顺序问题引发异常: 有时候我们使用写GUI程序的时候会遇到这样的问题:比如在程序中,建立了一个列表的GUI.这个列表是随着时间不断更新的,而且操作也会读取这个列表GUI的内容. 如果这个程序 ...
- Qt中(图片)资源的三种使用方式
Qt中使用图片资源的方法有很多种,以前我一直分不清各种之间的区别和Qt相应的处理机制,后来遇到一些实际的问题,然后再加上查阅源码和资料,总算弄明白一些事情,但是本文仅仅是个人理解,如有错误之处请告诉我 ...
随机推荐
- Mongodb数据模型
描述表关系的方式: 方式一:嵌入式 > db.person.find({name:'zjf'}).pretty() { "_id" : ObjectId("592f ...
- spring+mybatis 多数据源的配置
方式一: 参见博客https://www.cnblogs.com/AmbitiousMice/p/6027674.html 此种方式每次需要在调用dao的时候设置对应的数据源. 方式二: 直接在myb ...
- Django—ajax、前端后端编码格式,bulk_create批量插入语数据库、自定义分页
一.ajax简介: XML也是一门标记语言该语法应用场景 1.写配置文件 2.可以写前端页面(odoo框架中 erp) 每家公司都会有属于这家公司独有的内部管理软件:专门用来开发企业内部管理软件 框架 ...
- ssh转发流量的四种姿势
在很多时候拿到了内网的一台主机,我们需要用它做跳板来对内网进一步扩大战果. 也许方法很多,meterpreter,nc等等.但是最方便也最有可能穿透防火墙的方法,就是用ssh. 分为四种类型: 本地转 ...
- 手机端css实现active伪类
今天遇到手机端的css中a标签的active不起作用,原本想循环a标签,给当前的a标签添加class来解决,可觉得有点儿小麻烦,经查资料了解到解决此问题,只需要添加一个touchstart的空事件即可 ...
- 几种最常见的js array操作方法及示例
1. 序言 操作array可谓前端最基础的工作,无论是从接口中取的数据,还是筛选数据,或者是添加按钮权限等等操作,array都是绕不开的东西.array的操作很多,初学者十分容易搞混,不是很熟练的情况 ...
- python6---购物车程序
#!/usr/bin/env python#_author: harry#date: 2019.11.12# -*- coding: utf-8 -*-product_list =[ ('mac',9 ...
- Vue学习搭建(基础)
空项目:https://github.com/ElementUI/element-starter.git 参考教程:https://blog.csdn.net/xuehu837769474/artic ...
- DES加密 DESEncrypt
/// <summary> /// DES加密/解密类. /// </summary> public class DESEncrypt { public DESEncrypt( ...
- LOJ #2718. 「NOI2018」归程 Dijkstra+可持久化并查集
把 $Noi2018$ day1t1 想出来还是挺开心的,虽然是一道水题~ 预处理出来 1 号点到其它点的最短路,然后预处理边权从大到小排序后加入前 $i$ 个边的并查集. 这个并查集用可持久化线段树 ...