文章目录

  • 描述
  • 成员函数
  • 总结

描述

  • 头文件 <mutex>
  • 使用 std::mutex <variable>
  • 简介
    mutex是一种多线程变成中的同步原语,它能够让共享数据不被多个线程同时访问,它不支持递归得对互斥对象上锁
  • 特点
    • 用方线程从它成功调用 lock 或 try_lock 开始,到它调用 unlock 为止占有 mutex
    • 线程占有 mutex 时,所有其他线程若试图要求 mutex 的所有权,则将阻塞(对于 lock 的调用)或收到 false 返回值(对于 try_lock )
    • 调用方线程在调用 lock 或 try_lock 前必须不占有 mutex ,否则无法获取<mutex>变量

成员函数

  • 构造函数
    std::mutex::mutex

    constexpr mutex() noexcept;(1)
    mutex( const mutex& ) = delete;(2)
    

    (1)构造mutex实例,mutex实例构造完成之后是处于unlocked状态
    (2)mutex的拷贝构造函数是不存在的

  • std::mutex::~mutex析构函数
    销毁互斥变量
    若互斥为任何线程占有,或若任何线程在保有任何互斥的所有权时终止,则行为未定义

  • 赋值运算符,不存在

  • std::mutex::lock
    锁定互斥。若另一线程已锁定互斥,则到 lock 的调用将阻塞执行,直至获得锁
    错误发生时抛出 std::system_error ,包括底层操作系统阻止 lock 满足其规定的错误。在抛出任何异常的情况下,不锁定互斥。所以,直接使用mutex的lock成员是无处法处理异常的情况。

    #include <iostream>
    #include <chrono>
    #include <thread>
    #include <mutex>int g_num = 0;  // protected by g_num_mutex 共享数据
    std::mutex g_num_mutex;void slow_increment(int id)
    {for (int i = 0; i < 3; ++i) {g_num_mutex.lock();++g_num;std::cout << id << " => " << g_num << '\n';g_num_mutex.unlock();//chrono是C++的时间库,提供1s线程的休眠std::this_thread::sleep_for(std::chrono::seconds(1));}
    }int main()
    {//0号线程和1号线程交叉执行对全局变量g_num对累加操作,执行完成之后sleep 1秒std::thread t1(slow_increment, 0);std::thread t2(slow_increment, 1);t1.join();t2.join();
    }
    

    输出如下

    0 => 1
    1 => 2
    0 => 3
    1 => 4
    0 => 5
    1 => 6
    
  • std::mutex::try_lock
    尝试锁定互斥。立即返回。成功获得锁时返回 true ,否则返回 false。
    若此操作返回 true ,则同一互斥上的先前 unlock() 操作同步于(定义于 std::memory_order )它。注意若此操作返回 false ,则先前的 lock() 不与之同步

    #include <chrono>
    #include <mutex>
    #include <thread>
    #include <iostream> // std::coutstd::chrono::milliseconds interval(100);std::mutex mutex;
    int job_shared = 0; // 两个线程都能修改 'job_shared',// mutex 将保护此变量int job_exclusive = 0; // 只有一个线程能修改 'job_exclusive'// 不需要保护// 此线程能修改 'job_shared' 和 'job_exclusive'
    void job_1()
    {std::this_thread::sleep_for(interval); // 令 'job_2' 持锁while (true) {// 尝试锁定 mutex 以修改 'job_shared'if (mutex.try_lock()) {std::cout << "job shared (" << job_shared << ")\n";mutex.unlock();return;} else {// 不能获取锁以修改 'job_shared'// 但有其他工作可做++job_exclusive;std::cout << "job exclusive (" << job_exclusive << ")\n";std::this_thread::sleep_for(interval);}}
    }// 此线程只能修改 'job_shared'
    void job_2()
    {mutex.lock();std::this_thread::sleep_for(5 * interval);++job_shared;mutex.unlock();
    }int main()
    {/*可以看到job1中的实现,使用的是try_lock获取锁,因为刚开始job1线程会进行100毫秒的休眠,所以cpu会先去执行job2,但是job2使用的是lock成员所以在job2中sleep 500毫秒的过程中执行job1时try_lock返回false,则执行exclusive输出.当job2获取不到锁,job1休眠结束之后释放锁,则job1重新获取锁成功*/std::thread thread_1(job_1);std::thread thread_2(job_2);thread_1.join();thread_2.join();
    }
    

    输出如下

    job exclusive (1)
    job exclusive (2)
    job exclusive (3)
    job exclusive (4)
    job shared (1)
    
  • std::mutex::unlock解锁mutex实例
    使用前提是当前线程必须被mutex的实例锁定,否则改函数的调用是未定义的
    注意,当前成员与lock()成员,一般不直接调用,因为对异常情况的处理并不友好(程序锁定期间发生异常,进程就直接退出),所以一般与std::unique_lock 与 std::lock_guard 管理排他性锁 一起使用
    具体使用实例可以参考如上两个代码。

总结

mutex互斥变量,并提供来了独占锁特性。为C++提供了多线程访问共享数据的保护措施,同时引入了像unique_locklock_gurad异常处理锁机制来规避mutex的成员处理异常情况的不足。

C++多线程:互斥变量 std::mutex相关推荐

  1. C++多线程中互斥量std::mutex与模板类std::lock_guard

    一. 互斥量std::mutex C++中通过实例化std::mutex创建互斥量实例,通过成员函数lock()对互斥量上锁,unlock()进行解锁.C++中与std::mutex相关的类(包括锁类 ...

  2. C++11多线程---互斥量、锁、条件变量的总结

    关于互斥量std::mutex的总结 互斥量用于组成代码的临界区.C++的多线程模型是基于内存的,或者说是基于代码片段的,这和我们操作系统学习的临界区概念基本一致,但是与Golang不同,Golang ...

  3. linux的mutex状态查询命令,如何断言std :: mutex是否已锁定?

    使用GCC 4.8.2(在Linux / Debian / Sid 64位上)或GCC 4.9(在C ++ 11中可用)-我有一些互斥锁 std::mutex gmtx; 实际上,它是static某个 ...

  4. 【C++】多线程互斥锁、条件变量

    我们了解互斥量和条件变量之前,我们先来看一下为什么要有互斥量和条件变量这两个东西,了解为什么有这两东西之后,理解起来后面的东西就简单很多了!!! 先来看下面这段简单的代码: int g_num = 0 ...

  5. C++ 多线程:条件变量 std::condition_variable

    文章目录 描述 使用 描述 头文件<condition_variable> 定义 class condition_variable; 简介 之前我们也已经介绍过了C++多线程中互斥变量存在 ...

  6. 【多线程】多线程锁住的是什么、std::lock_guard<std::mutex> locker(mutex_)

    通常不直接使用 mutex,lock_guard更加安全, 更加方便. lock_guard简化了 lock/unlock 的写法, lock_guard在构造时自动锁定互斥量, 而在退出作用域时会析 ...

  7. 【多线程】1.条件变量--std::condition_variable

    条件变量允许我们通过通知进而实现线程同步. 因此,您可以实现发送方/接收方或生产者/消费者之类的工作流. 在这样的工作流程中,接收者正在等待发送者的通知.如果接收者收到通知,它将继续工作. 1. st ...

  8. C++多线程:异步操作std::async和std::promise

    文章目录 std::async 简介 使用案例 std::promise 简介 成员函数 总结 之前的文章中提到了C++多线程中的异步操作机制 C++ 多线程:future 异步访问类(线程之间安全便 ...

  9. std::atomic和std::mutex区别

    ​std::atomic介绍​ ​模板类std::atomic是C++11提供的原子操作类型,头文件 #include<atomic>.​在多线程调用下,利用std::atomic可实现数 ...

最新文章

  1. mysql年月分表_MySQL之按月拆分主表并按月分表写入数据提高数据查询速度
  2. PHP7+Swoole/Nginx/Golang性能对比
  3. python中列表数据汇总和平均值_python的列表List求均值和中位数实例
  4. linux unix shell programming,UnixampLinux Shell Programming I.ppt
  5. putty远程登录ssh主机
  6. bash error 环境变量错误
  7. 《美团数据平台及数仓建设实践》(209页).PDF
  8. LAMP架构调优(六)——开启长链接
  9. html给图片加文字,如何给图片加上字
  10. python编辑器怎么放大字体_增大python字体的方法步骤
  11. Android font-awesome 4.2 icons png(包含holo-light和holo-dark)
  12. 皮克公式 Peake‘s theorem
  13. 华为路由器hilink怎么用_华为HiLink是什么?华为hilink智能联网怎么用
  14. JavaScript控制光标定位操作
  15. 如何阻止搜索引擎收录指定网页
  16. 时序分析基本概念介绍--Timing Arc
  17. 编程环境和软件工具安装手册
  18. 智能停车场[简易版]
  19. JAVA 获取某天、某周、某月、某年的开始时间和结束时间
  20. 探索 Flutter 模拟事件触发 | 开发者说·DTalk

热门文章

  1. PCB的EMC设计之PCB叠层结构
  2. GridView中HyperLinkField的链接使用JavaScript问题
  3. 深度解析VC中的消息(上)
  4. 基于三维点云数据的主成分分析方法(PCA)的python实现
  5. 如果有的明星不会使用计算机,盘点娱乐圈不会用电脑手机的10大原始明星:最后一位出书都是手写...
  6. mysql 数字区间_币投君0904丨数字货币暴跌原因何在
  7. python最新版本 效率_Python:迭代列表与dict项目效率
  8. Keil C语言数据类型,KeilC的指针类型
  9. 第52章,bitmap图像处理(从零开始学android),第52章、Bitmap图像处理(从零开始学Android)...
  10. Keras ImageDataGenerator用于数据扩充/增强的原理及方法