C++11提供了两种管理锁的类
- std::lock_guard:与mutex RAII相关,方便线程对互斥量上锁
- std::unique_lock: 与mutex RAII相关,方便线程对互斥量上锁,相比std::lock_guard提供了更好的上锁和解锁控制
一 lock_guard详解
- lock_guard是一个模板类:template<classMutex>class lock_guard;
-
lock_guard对象通常用来管理某个锁(Lock)对象,与Mutex RALL相关,方便线程对互斥量上锁,在其声明周期内,它管理的锁一直保持上锁状态;在其声明周期结束之后,它锁管理的锁会被自动释放(即用构造函数对锁对象上锁,析构函数对锁对象解锁)
-
模板参数Mutex代表几种基本的BasicLockable类型分别为:std::mutex, std::recursive_mutex, std::timed_mutex, std::recursive_timed_mutex以及 std::unique_lock, (BasicLockable类型只需满足两种操作,lock和unlock。Lockable类型在BasicLockable的基础上增加了try_lock操作。TimedLockable类型在Lockable的基础上又增加了try_lock_for和try_lock_until操作。)
-
注意:lock_guard对象并不负责管理Mutex对象的生命周期,它只是简化了mutex的上锁和解锁操作,再其生命周期内,它锁管理的锁对象会一直保持上锁状态;声明周期结束之后,它锁管理的锁对象会被自动解锁。其最大的优点是安全易用(在出现异常时依旧可以正确解锁,一定程度上避免了死锁)。
-
lock_guard构造函数如下所示
-
locking-constructor (a) exlicit lock_guard(mutex_type& m);
adopting-constructor (b) lock_guard(mutex_type&m,adopt_lock_ttag);
copy(deleted) -constructor (c) lock_guard(const lock_guard&) = delete;
a locking-constructor
lock_guard对象管理Mutex对象m,并在构造时对m上锁
b adopting-constructor初始化
lock_guard对象管理Mutex对象m,与locking初始化不同的是,Mutex对象以被当前线程锁住。(将mutex对象用adopting::lock_guard管理,最终在调用lock_guard析构函数时,m锁对象会被自动解锁)
c copy-constructor
lock_guard的拷贝构造与移动构造均被禁用
-
locking-constructor examples
#include <iostream> #include <thread> #include <mutex> #include <stdexcept> std::mutex mtx; void printEven(int x) { if (0 == x % 2) { std::cout << x << " is even\n"; } else { throw (std::logic_error("not even\n")); } } void printThreadID(int id) { try { std::lock_guard<std::mutex>lck(mtx); printEven(id); } catch (std::logic_error&e) { //std::cout << e.what() << std::endl; std::cout << "[exception caught]\n"; } } int main(int argc, _TCHAR* argv[]) { std::thread threads[10]; for (int i = 0; i < 10;++i) { threads[i] = std::thread(printThreadID, i + 1); } for (auto &th : threads) { th.join(); } return 0; }
在voidprintThreadID(int id)中,首先捕捉voidprintEven(int x)中抛出的异常,在try块内,首先对mtx锁对象构造lock_guard对象lck(此语句之后,mtx锁对象由lck管理),即在try块作用域内(也就是lck对象生命周期内),mtx锁对象被上锁,在lck生命周期结束时mtx锁对象自动解锁(在抛出异常时,依旧可正确解锁)。
-
adopting-constructor example