用互斥元保护共享数据

线程相对于进程的优势在于能够共享数据,线程相对于进程的劣势也在于数据能够共享。如何多个线程安全的访问数据,你可以使用互斥锁保护数据,也可以优化数据结构使用无锁编程,或者使用事务保证数据同一时间只能被一个线程访问。

这里主要说的就是如何使用互斥锁对数据进行保护,使用互斥锁有一个问题就是需要使用者,在需要更改数据的时候调用lock()对数据加锁,在更改数据结束之后调用unlock()对数据解锁,如果漏掉解锁或者因为异常处理原因跳过解锁函数会导致死锁。

人为的去加锁和解锁不可避免的会出现只写了加锁而忘记解锁的情况,但是C++有一类函数会自动的执行,这些函数就是类的构造函数和类的析构函数,当创建类的时候自动的调用构造函数,当类销毁的时候就会调用析构函数,不需要人为的参与,这样就避免了因为人为的原因导致的死锁问题,C++已经提供了该类的实现,就是接下来要介绍的lock_guard函数

为了防止出现这种状况可以使用类的构造和析构进行数据的加锁和解锁

具体实现如下:

template<typename _Mutex>
class lock_guard
{public:typedef _Mutex mutex_type;// 调用构造函数 进行加锁explicit lock_guard(mutex_type& __m) : _M_device(__m){ _M_device.lock(); }lock_guard(mutex_type& __m, adopt_lock_t) noexcept : _M_device(__m){ } // calling thread owns mutex// 调用析构函数进行解锁~lock_guard(){ _M_device.unlock(); }lock_guard(const lock_guard&) = delete;lock_guard& operator=(const lock_guard&) = delete;private:mutex_type&  _M_device;
};

设计一个利用lock_guard进行加锁和解锁的demo如下:

//
// Created by andrew on 2021/3/31.
//
#include <iostream>
#include <list>
#include <mutex>
#include <algorithm>using namespace std;// 声明一个却局链表
list<int> g_list;
// 声明一个互斥锁用于保护全局链表数据
mutex list_mutex;void push_data_to_list(int newValue) {//    每次进来创建guard, 构造函数中会调用全局锁,在该函数退出的时候会自动调用析构函数实现
// 锁的释放lock_guard<std::mutex> guard(list_mutex);g_list.push_back(newValue);
}bool find_list_data(int valueData) {lock_guard<mutex> guard(list_mutex);return find(g_list.begin(), g_list.end(), valueData) != g_list.end();
}int main(int argc, char * argv[]) {push_data_to_list(42);cout << "find 1 = " << find_list_data(1) << "    find 42 = " << find_list_data(42) << endl;return 0;
}

使用互斥元保护共享数据-lock_guard相关推荐

  1. C++11使用互斥量保护共享数据

    C++中使用互斥量 在C++11中,可以通过实例化std::mutex创建互斥量,可以通过调用成员函数lock()进行上锁,调用unlock()进行解锁. 例如: int g_num = 0; std ...

  2. C++11保护共享数据的其他方法

    保护共享数据的初始化过程 在多线程编程中,互斥量是最通用的保护共享数据的机制.但是在某些情况下,一些资源仅需要在第一次初始化的时候需要保护,其时候就可以不需要互斥变量的保护了.比如编码中最常见的单例模 ...

  3. 正确使用锁保护共享数据,协调异步线程

    JMQ为提升性能,使用近乎无锁的设计: MQ中的锁是个必须使用的技术 使用锁会降低系统性能 如何正确使用锁? 异步和并发设计可大幅提升性能,但程序更复杂:多线程执行时,充斥不确定性.对一些需并发读写的 ...

  4. 用区块链保护共享数据?存储初创公司Gospel开始试水

    初创公司Gospel Technology声称正在利用区块链(Blockchain)来保护和验证可共享的数据.Gospel称,区块链技术的方法可以做到这一点,而且要比任何替代方法更简单. Gospel ...

  5. 《C++并发编程实战》读书笔记——chapter 3_线程间共享数据

    更多的阅读笔记,及示例代码见 Github https://github.com/anlongstory/C-_Concurrency_in_Action_reading_notes 本章主要内容: ...

  6. 保护线程间的共享数据

    程序员的自我修养(六):保护线程间的共享数据 多进程和多线程最本质的区别在于共享和隔离的程度不同.对于多进程方式来说,因为隔离程度高,所以程序员很少需要去担心进程空间的数据被破坏:但是并发任务之间共享 ...

  7. C++线程间共享数据

    通常我们使用锁保护线程间共享数据,这也是最基本的方式. 当访问共享数据前,使用互斥量将相关数据锁住,再当访问结束后,再将数据解锁.线程库需要保证,当一个线程使用特定互斥量锁住共享数据时,其他的线程想要 ...

  8. SUN平台,光纤共享存储互斥失败导致的数据灾难恢复

    作者:张宇,北亚数据恢复中心,转载请联系作者,如果实在不想联系作者,至少请保留版权,谢谢. [数据恢复故障描述] 两台SPARC SOLARIS系统通过光纤交换机共享同一存储,本意是作为CLUSTER ...

  9. Part5 数据的共享与保护 5.4类的友元5.5共享数据的保护

    友元是C++提供的一种破坏数据封装和数据隐藏的机制. 通过将一个模块声明为另一个模块的友元,一个模块能够引用到另一个模块中本是被隐藏的信息. 可以使用友元函数和友元类. 为了确保数据的完整性,及数据封 ...

最新文章

  1. android servlet 登陆,Android Studio+Servlet+MySql实现登录注册
  2. Linux NUMA 架构 :基础软件工程师需要知道一些知识
  3. 什么是物联网网关?物联网网关具备什么功能?_转
  4. Python--日志模块
  5. 从C#到Objective-C,循序渐进学习苹果开发(1)--准备开发账号和开发环境
  6. spring-boot中使用druid连接池
  7. Windows 磁盘分区方法
  8. 【报告分享】2019年用户生命周期运营白皮书(京东尼尔森出品).pdf(附下载链接)
  9. html 选择自动增加行数,HTML怎么自动计算出上两行的值在第三行里面?
  10. 前端开发的模块化和组件化的定义,以及两者的关系?
  11. 【水果识别】基于matlab GUI灰度+二值化+腐蚀+膨胀算法水果识别【含Matlab源码 671期】
  12. 世嘉MD游戏开发进阶篇【二】:C语言实现有限状态机
  13. Arduino Adafruit GFX图形库介绍(三)- 图形基本元素
  14. GitHub博客搭建
  15. 记录一个非常实用的gif制作工具licecap
  16. 一文看懂企业数据资产目录
  17. Python itertools accumulate函数详解
  18. Linux 源码分析 之 udp 分析 二 sendto
  19. 七牛云:用人工智能为内容安全保驾护航
  20. 【三】零基础入门深度学习:卷积神经网络基础之初识卷积

热门文章

  1. RH033 Unit 2 Linux Usage Basics
  2. hdu 5108(分解质因数)
  3. hdu 2896 病毒侵袭(AC自动机)
  4. Vue 动态路由的实现以及 Springsecurity 按钮级别的权限控制
  5. Android开发 listitem中采用倒计时
  6. HDU 5828 Rikka with Sequence (线段树+剪枝优化)
  7. bzoj2820: YY的GCD
  8. Python读入CIFAR-10数据库
  9. 系统安装重装与优化:chapter7 操作系统的修复与重装
  10. Python与C之间的相互调用