[modern c++] std::unique_lock的使用及其必要性

unique_lock在构造时的灵活性:

#include <iostream>
#include <Windows.h>
#include <mutex>
using namespace std;

void CriticalSection_2();

mutex m1;

void CriticalSection_1()
{
	unique_lock<mutex> lockguard(m1);						
	CriticalSection_2();
}

void CriticalSection_2()
{

		//场景一
		//unique_lock<mutex> lockguard(m1);						//崩溃,对已经加锁的 mutex 再加锁导致崩溃
	
	
		//场景二
		//unique_lock<mutex> lockguard(m1, try_to_lock_t());	//正常,对已经加锁的 mutex 尝试加锁不会导致崩溃
	
	
		//场景三
		//unique_lock<mutex> lockguard(m1, defer_lock_t());		//正常,对已经加锁的 mutex 不加锁不会崩溃
		//m1.lock();											//奔溃,对已经加锁的 mutex 再加锁导致崩溃
	
	
		//场景四
		//unique_lock<mutex> lockguard(m1, adopt_lock_t());		//崩溃 
	
}


int main()
{
	CriticalSection_1();

	std::cout << "Hello World!\n";
	while (1) Sleep(1000);
}

unique_lock在使用中的灵活性:

  • 可以随时解锁(lock_guard无法做到,虽然通过mutex.unlock()也可以完成,但是unique_lock提供了自释放功能)
#include <iostream>
#include <Windows.h>
#include <mutex>
using namespace std;

void CriticalSection_2();

mutex m1;

void CriticalSection_1()
{
	unique_lock<mutex> lockguard(m1);
	lockguard.unlock();
	CriticalSection_2();
}

void CriticalSection_2()
{
	unique_lock<mutex> lockguard(m1);						//正常,前面已经通过lockguard.unlock();进行了解锁
}


int main()
{
	CriticalSection_1();

	std::cout << "Hello World!\n";
	while (1) Sleep(1000);
}
  • 析构时会自动判断当前是否持有锁(对已经释放的锁再释放会导致崩溃,unique_lock在析构函数中会判断当前锁是否已经被释放)
#include <iostream>
#include <Windows.h>
#include <mutex>
using namespace std;

mutex m1;

void CriticalSection_1()
{
	unique_lock<mutex> lockguard(m1);
#if 1
	lockguard.unlock();					//不会奔溃,虽然lockguard.unlock();被显式调用,但是lockguard析构不会导致崩溃
#else
	m1.unlock();						//会崩溃,这里也要强调一点,如果打算使用unique_lock就不要在对原始的mutex进行任何操作
#endif
}


int main()
{
	CriticalSection_1();			
	std::cout << "Hello World!\n";
	while (1) Sleep(1000);
}

注意:

如果确定使用unique_lock了,就不要再使用 mutex 的 lock 和 unlock ,直接使用 unique_lock 的 lock 和 unlock,混合使用会导致程序异常,原因是unique_lock 内部会维护一个标识用来记录自己管理的 锁 当前处于何种状态,如果直接使用 mutex的成员函数,unique_lock无法更新自己的状态,从而导致 double lock 和 double unlock(因为unique_lock一定会在析构的时候unlock),这两种情况都会导致崩溃。

PS:

上面的崩溃不会发生在 递归锁上,所以上文中所有的锁 都是非递归锁,比如 mutex。

对比unique_lock 和 lock_guard:

  • 二者都是自释放锁;
  • lock_guard 在时间和空间上都比 unique_lock 要快;
  • lock_guard 功能单一,只能用作自释放锁;
  • unique_lock具备lock_guard的所有能力,同时提供更多的能力,比如锁的成员函数都会被封装后导出,同时不会引入 double lock 和 double unlock ;

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值