55、RAII技术---------多线程、竟态条件和同步
RAII技术RAIIResource Acquisition Is Initialization资源获取即初始化是一种C编程技术它将资源的获取例如分配的堆内存、打开的文件、锁定的互斥量等与对象的生命周期绑定在一起。具体来说RAII的核心思想是在对象的构造函数中获取资源并在对象的析构函数中释放资源。RAII的特点和优势1自动资源管理通过将资源的生命周期与对象的生命周期绑定RAII确保了资源在不再需要时自动释放避免了资源泄漏。2异常安全RAII能够提供异常安全性。如果在资源获取或使用过程中发生异常RAII对象会在其析构时自动释放资源从而避免了资源的泄漏。3简化代码使用RAII可以减少手动管理资源的复杂性使代码更加简洁和易于维护。4提高可读性资源的获取和释放是在对象的构造和析构中进行的使得资源管理的逻辑更加清晰。我们可以利用RAII思想创建一个MyLocker类这个类对象构造时加锁析构时解锁。#include QMutex class MyLocker { public: //构造函数接受互斥量并加锁 explicit MyLocker(QMutex* mtx); //析构函数解锁 ~ MyLocker(); //删除拷贝构造 MyLocker(const MyLocker ml) delete ; //删除拷贝赋值 MyLocker operator(const MyLocker ml) delete; //重写移动构造 MyLocker(MyLocker ml) noexcept; private: //互斥量指针 QMutex* _pointer_mtx; };具体实现#include mylocker.h MyLocker::MyLocker(QMutex *mtx):_pointer_mtx(mtx) { //加锁 _pointer_mtx-lock(); } MyLocker::~MyLocker() { //解锁 _pointer_mtx-unlock(); } //移动构造函数 MyLocker::MyLocker(MyLocker ml) noexcept:_pointer_mtx(ml._pointer_mtx) { }我们将原来的任务计算功能加锁改为我们自己封装的MyLocker类//线程开始后执行的任务 void ThreadWorker::slot_work() { _run true; int index 0; while(_run index 100000){ //使用我们自定义的MyLocker自动加锁 MyLocker locker(global_mtx); //对全局变量累加1 global_num 1; index; } //发送数字变化信号 emit sig_num_changed(global_num); //发送完成信号 emit sig_finished(); }那我问一下同学们MyLocker什么时候对互斥量global_mtx解锁的再次运行可以看到每次点击启动线程标签都是20万说明我们RAII封装的自动解锁很方便。