Qt-系统线程安全(63)

目录

描述

使用

线程不安全

线程安全

释放锁问题

其他的锁

条件变量和信号量


描述

多线程程序太复杂了

Qt-系统线程安全(63)

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

Qt-系统线程安全(63)

Qt-系统线程安全(63)?

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

Qt-系统线程安全(63)

使用

线程不安全

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

Qt-系统线程安全(63)

thread.h?

Qt-系统线程安全(63)

thread.cpp

一个简单的累加?

Qt-系统线程安全(63)

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

Qt-系统线程安全(63)

Qt-系统线程安全(63)

线程安全

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

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

Qt-系统线程安全(63)

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

Qt-系统线程安全(63)

?

Qt-系统线程安全(63)

释放锁问题

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

Qt-系统线程安全(63)

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

Qt-系统线程安全(63)?

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

Qt-系统线程安全(63)

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

Qt-系统线程安全(63)?

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

Qt-系统线程安全(63)

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

Qt-系统线程安全(63)

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

Qt-系统线程安全(63)

其他的锁

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(); //释放信号量
//在另?个线程中进?类似操作

上一篇:t41笔记本参数(我想买一台二手T系列的IBM笔记本,不知道哪一款比较好点都有什么配置和价位)
下一篇:32寸以下小尺寸电视机品牌(买什么电视好不同尺寸品牌推荐)