关于读写锁可查看:多线程之读写锁(unique_lock与shared_lock)

多个线程访问同一资源时,为了保证数据的一致性,最简单的方式就是使用 mutex(互斥锁)。

引用 cppreference 的介绍:

The mutex class is a synchronization primitive that can be used to protect shared data from being simultaneously accessed by multiple threads.

方法1:直接操作 mutex,即直接调用 mutex 的 lock / unlock 函数
此例顺带使用了 boost::thread_group 来创建一组线程。

#include <iostream>
#include <boost/thread/mutex.hpp>
#include <boost/thread/thread.hpp>boost::mutex mutex;
int count = 0;void Counter()
{mutex.lock();int i = ++count;std::cout << "count == " << i << std::endl;// 前面代码如有异常,unlock 就调不到了。mutex.unlock();
}int main()
{// 创建一组线程。boost::thread_group threads;for (int i = 0; i < 4; ++i) {threads.create_thread(&Counter);}// 等待所有线程结束。threads.join_all();return 0;
}

方法2:使用 lock_guard 自动加锁、解锁。原理是 RAII,和智能指针类似

#include <iostream>
#include <boost/thread/lock_guard.hpp>
#include <boost/thread/mutex.hpp>
#include <boost/thread/thread.hpp>boost::mutex mutex;
int count = 0;void Counter()
{//lock_guard 在构造函数里加锁,在析构函数里解锁。boost::lock_guard<boost::mutex> lock(mutex);int i = ++count;std::cout << "count == " << i << std::endl;
}int main()
{boost::thread_group threads;for (int i = 0; i < 4; ++i) {threads.create_thread(&Counter);}threads.join_all();return 0;
}

方法3:使用 unique_lock 自动加锁、解锁
unique_lock 与 lock_guard 原理相同,但是提供了更多功能(比如可以结合条件变量使用)。
注意:mutex::scoped_lock 其实就是 unique_lock<mutex> 的 typedef

#include <iostream>
#include <boost/thread/mutex.hpp>
#include <boost/thread/thread.hpp>boost::mutex mutex;
int count = 0;void Counter()
{boost::unique_lock<boost::mutex> lock(mutex);int i = ++count;std::cout << "count == " << i << std::endl;
}int main()
{boost::thread_group threads;for (int i = 0; i < 4; ++i) {threads.create_thread(&Counter);}threads.join_all();return 0;
}

关于join_all()函数可查看:多线程之std::thread join()函数

方法4:为输出流使用单独的 mutex
这么做是因为 IO 流并不是线程安全的!
如果不对 IO 进行同步,此例的输出很可能变成:

count == count == 2count == 41
count == 3

因为在下面这条输出语句中:

std::cout << "count == " << i << std::endl;

输出 "count == " 和 i 这两个动作不是原子性的(atomic),可能被其他线程打断。

注:原子性,原子是世界上的最小单位,具有不可分割性。比如 a=0;这个操作是不可分割的,那么我们说这个操作是原子操作。再比如:a++;这个操作实际是a = a + 1;是可分割的(先a+1,然后a=a+1),所以他不是一个原子操作。  非原子操作都会存在线程安全问题,需要我们使用同步技术(sychronized)来让它变成一个原子操作。一个操作是原子操作,那么我们称它具有原子性。

#include <iostream>
#include <boost/thread/mutex.hpp>
#include <boost/thread/thread.hpp>
#include <boost/thread/lock_guard.hpp>boost::mutex mutex;
boost::mutex io_mutex;
int count = 0;void Counter()
{int i;{boost::unique_lock<boost::mutex> lock(mutex);i = ++count;}{boost::unique_lock<boost::mutex> lock(io_mutex);std::cout << "count == " << i << std::endl;}
}int main()
{boost::thread_group threads;for (int i = 0; i < 4; ++i) {threads.create_thread(&Counter);}threads.join_all();return 0;
}

原文:c++并发编程之互斥锁(mutex)的使用方法

多线程之互斥锁(mutex)的使用方法相关推荐

  1. 互斥锁mutex的使用方法

    在线程实际运行过程中,我们经常需要多个线程保持同步.这时可以用互斥锁来完成任务:互斥锁的使用过程中,主要有pthread_mutex_init,pthread_mutex_destory,pthrea ...

  2. Linux下多线程编程互斥锁和条件变量的简单使用

    Linux下的多线程遵循POSIX线程接口,称为pthread.编写Linux下的多线程程序,需要使用头文件pthread.h,链接时需要使用库libpthread.a.线程是进程的一个实体,是CPU ...

  3. Multi_thread--Linux下多线程编程互斥锁和条件变量的简单使用

    Linux下的多线程遵循POSIX线程接口,称为pthread.编写Linux下的多线程程序,需要使用头文件pthread.h,链接时需要使用库libpthread.a.线程是进程的一个实体,是CPU ...

  4. android 线程互斥锁,线程锁(互斥锁Mutex)及递归锁

    一.线程锁(互斥锁) 在一个程序内,主进程可以启动很多个线程,这些线程都可以访问主进程的内存空间,在Python中虽然有了GIL,同一时间只有一个线程在运行,可是这些线程的调度都归系统,操作系统有自身 ...

  5. Linux多线程编程-互斥锁

    互斥锁 多线程编程中,(多线程编程)可以用互斥锁(也称互斥量)可以用来保护关键代码段,以确保其独占式的访问,这有点像二进制信号量.POSIX互斥锁相关函数主要有以下5个: #include <p ...

  6. 互斥锁(mutex)

    原文地址:https://blog.csdn.net/qq_39736982/article/details/82348672 Linux中提供一把互斥锁mutex(也称之为互斥量). 每个线程在对资 ...

  7. 互斥锁Mutex:鸿蒙轻内核中处理临界资源独占的“法官”

    摘要:本文带领大家一起剖析鸿蒙轻内核的互斥锁模块的源代码,包含互斥锁的结构体.互斥锁池初始化.互斥锁创建删除.申请释放等. 本文分享自华为云社区<鸿蒙轻内核M核源码分析系列十 互斥锁Mutex& ...

  8. 一文带你剖析LiteOS互斥锁Mutex源代码

    本文分享自华为云社区<LiteOS内核源码分析系列七 互斥锁Mutex>,原文作者:zhushy. 多任务环境下会存在多个任务访问同一公共资源的场景,而有些公共资源是非共享的临界资源,只能 ...

  9. 互斥锁(mutex lock)

    互斥锁 解决临界区最简单的工具就是互斥锁(mutex lock) 一个进程在进入临界区的时候获得锁(函数acquire) 在退出临界区时释放锁(函数release) 每个互斥锁都有一个布尔变量avai ...

最新文章

  1. shadow fight 1.6.0 内购
  2. SharePoint:扩展DVWP - 第21部分:实现可维护的三级联动下拉框
  3. 第一次正经面试之发现自己的缺陷和不足
  4. java学习(56):接口之间的继承续
  5. 环境变量_Jenkins流水线环境变量权威指南
  6. 套接字TCP控制台程序客户端代码示范
  7. 计算机应用类型分类 余额宝属于,按计算机应用的类型分类,余额宝属于。
  8. 不谈商业模式,为什么众筹新闻难成功
  9. 正弦波表(应该还会补充)
  10. 经典特别好用的局域网传输文件聊天工具飞秋和飞鸽传书
  11. LeetCode 56~60
  12. 用计算机制作母亲贺卡,母亲节电子贺卡制作
  13. Tiptop CR报表axcr700采购入库月报增加tlf99“多角贸易序号”,部分资料无数据修复4gl文件bug
  14. 最详细的虚拟机安装教程
  15. 浮点数除0和余0、定义
  16. java url正则校验,Java正则验证
  17. java返回一个布尔值_关于java:返回布尔值的方法
  18. 备案 - 多个域名同时备案
  19. 第1章:QLableButty
  20. c#导入地图(一)--地图Gmap的使用

热门文章

  1. 面试问到DCL失效不知所措
  2. 前端跨域问题—解决Firefox浏览器显示“已阻止载入混合活动内容”的方法
  3. WINcc 导出历史数据
  4. MySQL的时间戳(Timestamp)类型学习
  5. 数据分析师—Excel函数篇
  6. 第三方登录之微信登录
  7. compareTo的用法
  8. 深剖基类和派生类的虚函数表
  9. Mac Xnip 截图软件快捷键设置
  10. 解决docer login报错 panic: runtime error: invalid memory address or nil pointer dereference