细谈lock_guard与shared_lock与unique_lock的区别

C++互斥锁(互斥量)封装在Mutex类中,每个线程在对资源操作前都尝试先加锁,成功加锁才能操作,操作结束解锁。同一时刻,只能有一个线程持有该锁。
细谈lock_guard与shared_lock与unique_lock的区别_第1张图片
互斥锁通过调用类成员函数lock()与unlock()来实现加锁和解锁操作。
读写锁也叫做“共享-独占锁”,当读写锁以读模式锁住时,它是以共享模式锁住的;当它以写模式锁住时,它是以独占模式锁住的。当读写锁处于写加锁状态时,在其解锁之前,所有尝试对其加锁的线程都会被阻塞;
当读写锁处于读加锁状态时,所有试图以读模式对其加锁的线程都可以得到访问权,但是如果想以写模式对其加锁,线程将阻塞。
1、lock_guard:
(1)创建即加锁,作用域结束自动析构解锁,无需手工解锁。
(2)且不能中途解锁,必须等作用域结束才能解锁。
(3)缺点在于在定义lock_guard的地方会调用构造函数加锁,在离开定义域时lock_guard就会被销毁,调用析构函数解锁。如果定义域范围很大的话,锁的粒度就会很大,影响效率。
2、unique_lock
当一个函数内部有两段代码需要保护时,这个时候使用lock_guard就需要创建两个局部对象来管理一个同斥锁,修改方法是使用unique_lock,它提供lock()和unlock()接口,能记录现在是处于上锁还是未上锁状态。
std::unique_lockguard(_mu);
guard.unlock();//临时解锁
guard.lock(); //临时上锁
而unique_lock在析构的时候会判断当前锁的状态来决定是否解锁,如果已经是解锁状态了,就不会再次解锁了,效率较慢。unique_lock是write lock。被锁后不允许其他线程执行被shared_lock或unique_lock的代码。
3、shared_lock可用于保护共享数据不被多个线程同时访问。std::shared_lock::lock
以共享模式锁定关联互斥。等效于调用 mutex.lock_shared();用于获得互斥的共享所有权。若另一线程以排他性所有权保有互斥,则到 lock_shared 的调用将阻塞执行,直到能取得共享所有权。shared_lock是read lock。被锁后仍允许其他线程执行同样被shared_lock的代码。这是一般做读操作时的需要。
4、std:adopt_lock称为自适应锁,用于判断。表示可传递给lock_guard和unique_lock的构造函数,假设调用一方已经lock成功了,则通知lock_guard不需要再构造函数中lock这个互斥量了(就是不需要再锁了)。

你可能感兴趣的:(c++,锁)