多线程中的互斥锁

互斥量mutex

类对象,理解成一把锁,多个线程尝试用lock()成员函数来对其加锁,只有一个线程能够锁定成功

lock( ) 与unlock( )须成对存在,很容易出问题, 所以引入**std::lock_guard()**类模板,对于忘记添加unlock(),会自动添加,类似于智能指针的功能。

锁住的代码量多少成为粒度的粗细,粒度越细,代码执行效率越高。

死锁

至少有两个互斥量(锁头)才会产生死锁。避免方法:只要保证互斥量上锁的顺序一致就不会产生死锁。

std::.lock()处理多个互斥量才派的上用场。【谨慎使用】

adopt_lock是一个结构体对象,起一个标记作用:表示互斥量已经lock(),不需要在std::lock_guard<std::mutex> mguard(m_mutex1)再次lock();

// 方法1:
m_mutex2.lock();
m_mutex1.lock();
//---------------
m_mutex2.unlock();
m_mutex1.unlock();
//-------------
m_mutex2.lock();  // 与前面上锁顺序一致
m_mutex1.lock();
//---------------
m_mutex2.unlock();
m_mutex1.unlock();

//  方法2:
std::lock_guard<std::mutex> mguard1(m_mutex1);
std::lock_guard<std::mutex> mguard2(m_mutex2);
//------------------------------
std::lock_guard<std::mutex> mguard1(m_mutex1);
std::lock_guard<std::mutex> mguard2(m_mutex2);

// 方法3:结合std::lock()和lock_guard(),使用adop_lock
std::lock(m_mutex1, m_mutex2);
std::lock_guard<std::mutex> mguard1(m_mutex1, std::adopt_lock);
std::lock_guard<std::mutex> mguard2(m_mutex2, std::adopt_lock);
// 后面无须再unlock();

unique_lock可以完全取代lock_guard

工作中一般使用lock_guard

unique_lock比lock_guard灵活,内存占用多一点

第二个参数:

  • adopt_lock:用之前先lock()
  • try_to_lock:不能先lock(),尝试加锁,用mguard.owns_lock()判断是否加锁成功
  • defer_lock:不能先lock(),初始化一个没有加锁的mutex对象,而后用mguard.lock()加锁
std::unique_lock<std::mutex> mguard(m_mutex, std::defer_lock);

unique_lock的成员函数:

  • lock()
  • unlock()
  • try_lock():尝试加锁返回布尔值,类似于mguard.owns_lock()
  • release():返回管理的mutex对象指针,并释放所有权,即unique_lock与mutex不载有关系。
std::unique_lock<std::mutex> mguard(m_mutex);
std::mutex* pt = mguard.release(); // 此时pt相当于m_mutex,解除关联,有责任手动解锁
//--------------------
pt->unlock();

unique_lock所有权的传递

std::unique_lock<std::mutex> mguard1(m_mutex);
std::unique_lock<std::mutex> mguard2(std::move(mguard1));

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

量子孤岛

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值