@ 转载
看着这个老哥写的不错悄悄转过来
std::lock_guard使用起来比较简单,其在构造函数中对std::mutex变量进行锁定,在其析构函数中对std::mutex变量进行解锁,整个类没有对mutex进行解锁和加锁的对外接口,其源码如下:
templateclass _LIBCPP_TYPE_VIS_onLY lock_guard { public: typedef _Mutex mutex_type; private: mutex_type& __m_; public: _LIBCPP_INLINE_VISIBILITY explicit lock_guard(mutex_type& __m) : __m_(__m) {__m_.lock();} _LIBCPP_INLINE_VISIBILITY lock_guard(mutex_type& __m, adopt_lock_t) : __m_(__m) {} _LIBCPP_INLINE_VISIBILITY ~lock_guard() {__m_.unlock();} private: lock_guard(lock_guard const&);// = delete; lock_guard& operator=(lock_guard const&);// = delete; };
使用方法如下:
std::mutex g_mutex;
int g_var = 0;
void test_guard()
{
std::lock_guard guard(g_mutex);
g_var ++;
}
unique_lock
unique_lock相比lock_guard,功能要多很多,其提供了对mutex的加锁(lock和try_lock)和解锁(unlock)操作,同时可以配合条件变量condition_variable使用:
templateunique_lock和lock_guard的区别class _LIBCPP_TYPE_VIS_ONLY unique_lock { public: typedef _Mutex mutex_type; private: mutex_type* __m_; bool __owns_; public: _LIBCPP_INLINE_VISIBILITY unique_lock() _NOEXCEPT : __m_(nullptr), __owns_(false) {} _LIBCPP_INLINE_VISIBILITY explicit unique_lock(mutex_type& __m) : __m_(&__m), __owns_(true) {__m_->lock();} _LIBCPP_INLINE_VISIBILITY unique_lock(mutex_type& __m, defer_lock_t) _NOEXCEPT : __m_(&__m), __owns_(false) {} _LIBCPP_INLINE_VISIBILITY unique_lock(mutex_type& __m, try_to_lock_t) : __m_(&__m), __owns_(__m.try_lock()) {} _LIBCPP_INLINE_VISIBILITY unique_lock(mutex_type& __m, adopt_lock_t) : __m_(&__m), __owns_(true) {} template _LIBCPP_INLINE_VISIBILITY unique_lock(mutex_type& __m, const chrono::time_point<_Clock, _Duration>& __t) : __m_(&__m), __owns_(__m.try_lock_until(__t)) {} template _LIBCPP_INLINE_VISIBILITY unique_lock(mutex_type& __m, const chrono::duration<_Rep, _Period>& __d) : __m_(&__m), __owns_(__m.try_lock_for(__d)) {} _LIBCPP_INLINE_VISIBILITY ~unique_lock() { if (__owns_) __m_->unlock(); } private: unique_lock(unique_lock const&); // = delete; unique_lock& operator=(unique_lock const&); // = delete; public: #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES _LIBCPP_INLINE_VISIBILITY unique_lock(unique_lock&& __u) _NOEXCEPT : __m_(__u.__m_), __owns_(__u.__owns_) {__u.__m_ = nullptr; __u.__owns_ = false;} _LIBCPP_INLINE_VISIBILITY unique_lock& operator=(unique_lock&& __u) _NOEXCEPT { if (__owns_) __m_->unlock(); __m_ = __u.__m_; __owns_ = __u.__owns_; __u.__m_ = nullptr; __u.__owns_ = false; return *this; } #endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES void lock(); bool try_lock(); template bool try_lock_for(const chrono::duration<_Rep, _Period>& __d); template bool try_lock_until(const chrono::time_point<_Clock, _Duration>& __t); void unlock(); _LIBCPP_INLINE_VISIBILITY void swap(unique_lock& __u) _NOEXCEPT { _VSTD::swap(__m_, __u.__m_); _VSTD::swap(__owns_, __u.__owns_); } _LIBCPP_INLINE_VISIBILITY mutex_type* release() _NOEXCEPT { mutex_type* __m = __m_; __m_ = nullptr; __owns_ = false; return __m; } _LIBCPP_INLINE_VISIBILITY bool owns_lock() const _NOEXCEPT {return __owns_;} _LIBCPP_INLINE_VISIBILITY _LIBCPP_EXPLICIT operator bool () const _NOEXCEPT {return __owns_;} _LIBCPP_INLINE_VISIBILITY mutex_type* mutex() const _NOEXCEPT {return __m_;} };
简单的说,unique_lock相对于lock_guard,会有更多特性。
-
unique_lock和lock_guard都遵循RAII。
-
unique_lock和lock_guard最大的不同是:unique_lock不需要始终拥有关联的mutex,而lock_guard始终拥有mutex。
这意味着unique_lock需要利用owns_lock()判断是否拥有mutex。
另外,如果要结合使用条件变量,应该使用unique_lock。
参考[StackOverflow]



