c++ unique_lock与lock_guard的区别
来源:互联网 发布:杨氏模量测量实验数据 编辑:程序博客网 时间:2024/06/05 06:19
std::lock_guard是c++的模板类,定义如下:
template class lock_guard
lock_guard 对象通常用于管理某个锁(Lock)对象,因此与 Mutex RAII 相关,方便线程对互斥量上锁,即在某个 lock_guard 对象的声明周期内,它所管理的锁对象会一直保持上锁状态;而 lock_guard 的生命周期结束之后,它所管理的锁对象会被解锁。
模板参数Mutexx代表互斥量类型,他是一个基本的BasicLockable 类型,标准库中中定义的几种基本BasicLockable 类型,分别 std::mutex, std::recursive_mutex,std::timed_mutex,std::recursive_timed_mutex
以及std::unique_lock。
在lock_guard对象构造时,传入的Mutex对象会被当前线程锁住,在lock_guard析构时被解锁,所以不需要我们进行手动的解锁操作,提高了程序的正确率,尤其是当程序出现异常导致程序提前结束,有可能你的mutex对象还未被解锁就已经被跳过了,而lock_guard则替我们很好的解决了这个问题,无论程序是异常还是正常结束,lock_guard的析构函数总会被调用,即mutex对象总会被解锁,极大地简化了程序员编写与 Mutex 相关的异常处理代码。
观察下面的简单代码:
#include <iostream> // std::cout#include <thread> // std::thread#include <mutex> std::mutex mtx; // mutex for critical sectionvoid print_thread_id (int id) { mtx.lock(); std::lock_guard<std::mutex> lck(mtx, std::adopt_lock); std::cout << "thread #" << id << '\n';}int main (){ std::thread threads[10]; // spawn 10 threads: for (int i=0; i<10; ++i) threads[i] = std::thread(print_thread_id,i+1); for (auto& th : threads) th.join(); return 0;}
在函数print_thread_id中,首先对mtx进行上锁操作,然后用mtx对象构造一个lock_guard对象,此时当前线程已经获得了锁,然后mtx的解锁操作由lock_guard的析构函数完成,即当lock_guard对象被销毁时,当前线程被自动解锁。
std::lock_guard最大的优点也是最大的缺点便是简单,没有给程序员提供足够的灵活度, 与我们便需要使用另一个与Mutex RAII的相关类unique_lock,该类与lock_guard相似。但unique_lock对象以独占所有权的方式管理mutex对象的上锁和解锁操作,所谓独占所有权,就是没有其他的unique_lock对象同时拥有某个mutex对象的所有权。
在构造(或移动(move)赋值)时,unique_lock 对象需要传递一个 Mutex 对象作为它的参数,新创建的 unique_lock 对象负责传入的 Mutex 对象的上锁和解锁操作。
unique_lock的构造函数:
- unique_lock() noexcept;
- explicit unique_lock(mutex_type& m);
- unique_lock(mutex_type& m, try_to_lock_t tag);
- unique_lock(mutex_type& m, defer_lock_t tag) noexcept;
- unique_lock(mutex_type& m, adopt_lock_t tag);
- template (class Rep, class Period)unique_lock(mutex_type& m, const chrono::durationRep,Period>& rel_time);
- template class Clock, class Duration
unique_lock(mutex_type& m, const chrono::time_point Clock,Duration>& abs_time);
(1) 默认构造函数
新创建的 unique_lock 对象不管理任何 Mutex 对象。
(2) locking 初始化
新创建的 unique_lock 对象管理 Mutex 对象 m,并尝试调用 m.lock() 对 Mutex 对象进行上锁,如果此时另外某个 unique_lock 对象已经管理了该 Mutex 对象 m,则当前线程将会被阻塞。
(3) try-locking 初始化
新创建的 unique_lock 对象管理 Mutex 对象 m,并尝试调用 m.try_lock() 对 Mutex 对象进行上锁,但如果上锁不成功,并不会阻塞当前线程。
(4) deferred 初始化
新创建的 unique_lock 对象管理 Mutex 对象 m,但是在初始化的时候并不锁住 Mutex 对象。 m 应该是一个没有当前线程锁住的 Mutex 对象。
(5) adopting 初始化
新创建的 unique_lock 对象管理 Mutex 对象 m, m 应该是一个已经被当前线程锁住的 Mutex 对象。(并且当前新创建的 unique_lock 对象拥有对锁(Lock)的所有权)。
(6) locking 一段时间(duration)
新创建的 unique_lock 对象管理 Mutex 对象 m,并试图通过调用 m.try_lock_for(rel_time) 来锁住 Mutex 对象一段时间(rel_time)。
(7) locking 直到某个时间点(time point)
新创建的 unique_lock 对象管理 Mutex 对象m,并试图通过调用 m.try_lock_until(abs_time) 来在某个时间点(abs_time)之前锁住 Mutex 对象。
unique_lock支持移动赋值操作,但普通的赋值被禁止了,即有move操作,但是禁止(operator = )操作。
unique_lock的主要成员函数,
1.上锁/解锁操作:lock,try_lock,try_lock_for,try_lock_until 和 unlock
2.修改操作:移动赋值(move assignment)(前面已经介绍过了),交换(swap)(与另一个 std::unique_lock 对象交换它们所管理的 Mutex 对象的所有权),释放(release)(返回指向它所管理的 Mutex 对象的指针,并释放所有权)。
3.获取属性操作:owns_lock(返回当前 std::unique_lock 对象是否获得了锁)、operator bool()(与 owns_lock 功能相同,返回当前 std::unique_lock 对象是否获得了锁)、mutex(返回当前 std::unique_lock 对象所管理的 Mutex 对象的指针)。
返回std::unique_lock对象多管理的Mutex对象的指针
#include <iostream> // std::cout#include <thread> // std::thread#include <mutex> // std::mutex, std::unique_lock, std::defer_lockclass MyMutex : public std::mutex { int _id;public: MyMutex (int id) : _id(id) {} int id() {return _id;}};MyMutex mtx (101);void print_ids (int id) { std::unique_lock<MyMutex> lck (mtx); std::cout << "thread #" << id << " locked mutex " << lck.mutex()->id() << '\n';}int main (){ std::thread threads[10]; // spawn 10 threads: for (int i=0; i<10; ++i) threads[i] = std::thread(print_ids,i+1); for (auto& th : threads) th.join(); return 0;}
- c++ unique_lock与lock_guard的区别
- lock_guard和unique_lock的区别
- std::lock_guard 和 std::unique_lock的区别
- std::lock_guard std::unique_lock 区别
- C++11中lock_guard和unique_lock的区别
- c++11的mutex unique_lock和lock_guard区别
- C++11 std::unique_lock与std::lock_guard区别及多线程应用实例
- Thread lock_guard 和 unique_lock
- 线程自动加锁与自动解锁:lock_guard & unique_lock
- std::mutex std::unique_lock std::lock_guard std::recursive_mutex的理解
- boost::unique_lock vs boost::lock_guard
- std::lock_guard and std::unique_lock
- 锁对象---lock_guard和unique_lock
- c++ 11 lock_guard/unique_lock详解
- boost锁scope_lock与lock_guard区别
- boost中shared_lock和unique_lock的区别
- boost shared_lock unique_lock区别
- std::lock_guard 引起的思考
- 1120. Friend Numbers (20) <set>
- IdentityActivator()
- 利息、汇率与外汇
- 大话设计模式读后感之装饰模式
- 高可用、开源的Redis缓存集群方案
- c++ unique_lock与lock_guard的区别
- [USACO3.2]纺车的轮子 Spinning Wheels
- System.IO.Directory.GetCurrentDirectory与System.Windows.Forms.Application.StartupPath的用法
- VC++(unicode)实现URLDecode函数,对URl编码的字符串进行解码
- Cache 的作用
- 7.IDA-创建结构体
- 基于AWS搭载laravel
- 常见开源协议简介
- git ignore~