C++11之lock_guard学习总结和代码实例
2016-07-27 22:47
417 查看
std::lock_gurad 是 C++11 中定义的模板类。定义如下:
在 lock_guard 对象构造时,传入的 Mutex 对象(即它所管理的 Mutex 对象)会被当前线程锁住。在lock_guard 对象被析构时,它所管理的 Mutex 对象会自动解锁,由于不需要程序员手动调用 lock 和 unlock 对 Mutex 进行上锁和解锁操作,因此这也是最简单安全的上锁和解锁方式,尤其是在程序抛出异常后先前已被上锁的 Mutex 对象可以正确进行解锁操作,极大地简化了程序员编写与 Mutex 相关的异常处理代码。
代码中
lock_guard(const lock_guard&) = delete;
lock_guard& operator=(const lock_guard&) = delete;
禁用了拷贝构造函数和赋值构造函数.保证了 lock_guard 对象的所有权不会被转移.
代码参考地址,这哥们讲解的很透彻,
http://blog.csdn.net/liuxuejiang158blog/article/details/17241387
代码实例1:使用固定顺序获取锁
代码实例2:层次锁
lock hierarchy指的是给每个mutex分配一个标号从而对mutex逻辑排序。限制条件是:当线程已经持有编号比n小的锁时不能再请求标号为n的mutex.
template<class _Mutex> class lock_guard { // class with destructor that unlocks mutex public: typedef _Mutex mutex_type; explicit lock_guard(_Mutex& _Mtx) : _MyMutex(_Mtx) { // construct and lock _MyMutex.lock(); } lock_guard(_Mutex& _Mtx, adopt_lock_t) : _MyMutex(_Mtx) { // construct but don't lock } ~lock_guard() _NOEXCEPT { // unlock _MyMutex.unlock(); } lock_guard(const lock_guard&) = delete; lock_guard& operator=(const lock_guard&) = delete; private: _Mutex& _MyMutex; };
在 lock_guard 对象构造时,传入的 Mutex 对象(即它所管理的 Mutex 对象)会被当前线程锁住。在lock_guard 对象被析构时,它所管理的 Mutex 对象会自动解锁,由于不需要程序员手动调用 lock 和 unlock 对 Mutex 进行上锁和解锁操作,因此这也是最简单安全的上锁和解锁方式,尤其是在程序抛出异常后先前已被上锁的 Mutex 对象可以正确进行解锁操作,极大地简化了程序员编写与 Mutex 相关的异常处理代码。
代码中
lock_guard(const lock_guard&) = delete;
lock_guard& operator=(const lock_guard&) = delete;
禁用了拷贝构造函数和赋值构造函数.保证了 lock_guard 对象的所有权不会被转移.
代码参考地址,这哥们讲解的很透彻,
http://blog.csdn.net/liuxuejiang158blog/article/details/17241387
代码实例1:使用固定顺序获取锁
#include <mutex> #include<unistd.h> #include<thread> #include<iostream> using namespace std; class big_object { public: big_object(int i=0):data(i){} public: int data; }; void swap(big_object& lhs,big_object& rhs) { sleep(1); cout<<"swap()"<<endl; } class X { private: big_object some_detail; mutable std::mutex m; public: X(big_object const& sd):some_detail(sd){} friend void swap(X& lhs, X& rhs) { if(&lhs==&rhs) return; std::lock(lhs.m,rhs.m);//C++库会自动生成加锁顺序,即使调用顺序不一致 std::lock_guard<std::mutex> lock_a(lhs.m,std::adopt_lock);//adopt_lock是告诉lock_guard对象mutex已经被上锁,而lock_gurad对象将获得mutex的所有权,这样就可以保证在lock可能出现异常导致没有unlock的情形不会出现,栈对象会在异常抛出后自动析构 std::lock_guard<std::mutex> lock_b(rhs.m,std::adopt_lock); swap(lhs.some_detail,rhs.some_detail); } }; void threadFun(X& one,X& two){ swap(one,two); } int main() { big_object ten(10),hundred(100); X one(ten),two(hundred); thread threadOne(threadFun,ref(one),ref(two));//不同线程有不同的参数调用顺序,ref表示传递的是引用,否则只有线程函数中传引用无效 thread threadTwo(threadFun,ref(two),ref(one)); threadOne.join(); threadTwo.join(); return 0; }
代码实例2:层次锁
lock hierarchy指的是给每个mutex分配一个标号从而对mutex逻辑排序。限制条件是:当线程已经持有编号比n小的锁时不能再请求标号为n的mutex.
#include <mutex> #include <stdexcept> class hierarchical_mutex//可用于lock_guard<hierarchical_mutex> { std::mutex internal_mutex;// unsigned long const hierarchy_value;//mutex所在的层次 unsigned long previous_hierarchy_value;//记录前一个mutex的层次,用于解锁时恢复线程的层次 static thread_local unsigned long this_thread_hierarchy_value;//线程所在的层次,是个线程私有数据 void check_for_hierarchy_violation()//检查当前mutex是否小于线程层次,不是则抛出异常 { if(this_thread_hierarchy_value <= hierarchy_value) { throw std::logic_error("mutex hierarchy violated"); } } void update_hierarchy_value()//更新线程的层次 { previous_hierarchy_value=this_thread_hierarchy_value;//通过previous_hierarchy_value记住线程的层次 this_thread_hierarchy_value=hierarchy_value;//用当前mutex的层次更新线程层次 } public: explicit hierarchical_mutex(unsigned long value): hierarchy_value(value),//mutex层次初始值 previous_hierarchy_value(0) {} void lock()//对mutex加锁 { check_for_hierarchy_violation();//先检查,保证mutex层次小于线程层次 internal_mutex.lock(); update_hierarchy_value();//更新线程层次 } void unlock()//对mutex解锁 { this_thread_hierarchy_value=previous_hierarchy_value;//用记录的previous_hierarchy_value恢复线程层次 internal_mutex.unlock(); } bool try_lock()//尝试加锁,若mutex已被其它上锁则返回false { check_for_hierarchy_violation(); if(!internal_mutex.try_lock()) return false; update_hierarchy_value(); return true; } }; thread_local unsigned long hierarchical_mutex::this_thread_hierarchy_value(ULONG_MAX);//线程层次初始值为最大,保证开始可以对任意mutex上锁
相关文章推荐
- c++11 + SDL2 + ffmpeg +OpenAL + java = Android播放器
- C++11的for循环,以及范围Range类的简单实现
- C++11的新特性简单汇总介绍 (二)
- C++11的新特性简单汇总介绍 (一)
- Java 线程同步详解
- c#线程同步使用详解示例
- Linux线程同步之信号C语言实例
- Python中使用Queue和Condition进行线程同步的方法
- Java线程同步实例分析
- JAVA生产者消费者(线程同步)代码学习示例
- 详解Java多线程编程中的线程同步方法
- 多线程问题及处理方法【转】
- 在 Qt4 中使用 C++11
- 线程同步问题
- c++11新特性--decltype auto
- centos安装devtoolset-3支持gcc 4.9.2
- c++11学习笔记
- 【Java基础】线程同步教程
- IOS之多线程
- 使用eclipse编译含有C++11特性的代码