学习网址:
C/C++编程:std::mutex 详解
https://blog.csdn.net/zhizhengguan/article/details/107353387
互斥量
std::mutex
摘自网址
https://www.cnblogs.com/qbin/p/13294795.html
调用的线程会锁住互斥量(mutex),必要的话会被阻塞:
1.如果其它任何线程没有对互斥量进行锁操作,调用线程会对互斥量进行锁操作
(从这一时刻开始,直到调用unlock,互斥量为调用线程拥有)
2.如果其它线程又锁住互斥量,再次执行lock的线程会被阻塞,直到拥有互斥量的线程调用unlock
(其它未对互斥量进行操作的线程继续执行各自任务)
3.如果互斥量已经被调用lock的线程锁住,它会导致死锁(出现未定义表现)。
查看recursive_mutex,了解互斥量类型,部分互斥量允许在同一个线程里进行多次锁操作。
std::recursive_mutex:
是一个递归互斥量,同一个线程可以多次调用锁定:
和互斥量(mutex)一样,一个递归互斥量(recursive mutex)是一个可锁的对象,只是它允许同一个线程对互斥量对象获取多级所有权。
如此,它允许已进行了锁操作的线程,再次lock(或try-lock)互斥量对象,获取该互斥量对象一个新所有权:互斥量对象一直为拥有线程锁住,在调用unlock的次数和lock次数相同前。
这是一个标准的布局类。
std::mutex和std::recursive_mutex区别:
std:mutex: 同一个线程只能锁一次,有顺序的执行,会阻塞
std:recursive_mutex: 递归锁,同一个线程可以多次锁
为什么std:mutex和std:lock_guard配合使用
std::mutex是C++11中最基本的mutex类,通过实例化std::mutex可以创建互斥,而通过lock()可以上锁,unlock可以解锁。但是在实际编写代码的过程中,最好不要去直接调用成员函数,因为调用成员成员需要在每个临界区的出口处调用unlock(),当然,还包括异常的原因。
为解决这个问题,C++11为互斥量提供了一个RAII语法的模板类std::lock_guard。RAII在不失代码简洁性的同时,很好的保证了代码的异常安全性。
使用例子:
static std::mutex m_muxInstance;
//作用域
{
std::lock_guard<mutex> mlock(m_muxInstance);
}
std::unique_lock 和std:lock_guard的区别
std::unique_lock是相对于std::lock_gurad出现的,std::unique_lock更加灵活,
std::unique_lock的对象会以独占所有权的方式管理mutex对象上的上锁和解锁的操作,
(没有其他的unique_lock对象同时拥有某个mutex对象的所有权)
所以在并发编程中,推荐使用std::unique_locck。