互斥锁
互斥锁的应用场景,对共享的数据进行写保护,以防止多线程在对共享数据成员进行读写时造成资源争抢导致程序出现未定义的行为。
简单例子
先看一段代码
#include <iostream>
#include <thread>
#include <string>
using namespace std;
void Print()
{
for (int i = 0; i < 10; i++) {
cout << "print thread: " << i << endl;
}
}
int main()
{
thread t(Print);
for (int i = 0; i > -10; i--) {
cout << "print main: " << i << endl;
}
t.join();
return 0;
}
因为多线程执行的顺序,是CPU根据时间片随机调度的,每次执行顺序不固定,输出结果也不定。
怎么可以固定下来呢?
用互斥锁。
用互斥锁的例子
#include <iostream>
#include <thread>
#include <mutex>
#include <string>
using namespace std;
mutex mtx;
void Print()
{
mtx.lock();
for (int i = 0; i < 10; i++) {
cout << "print thread: " << i << endl;
}
mtx.unlock();
}
int main()
{
thread t(Print);
mtx.lock();
for (int i = 0; i > -10; i--) {
cout << "print main: " << i << endl;
}
mtx.unlock();
t.join();
return 0;
}
互斥锁的用法
std::mutex 是C++11 中最基本的互斥锁,std::mutex 对象提供了独占所有权的特性——即不支持递归地对
std::mutex 对象上锁,而 std::recursive_lock 则可以递归地对互斥量对象上锁。
成员函数:lock、unlock、try_lock
除了mutex类,c++11还提供了lock_guard和unique_lock。
lock_guard
std::lock_gurad 是 C++11 中定义的模板类。定义如下:
template <class Mutex>
class lock_guard;
lock_guard 对象通常用于管理某个锁(Lock)对象,因此与 Mutex RAII 相关,方便线程对互斥量上锁,即在某个 lock_guard 对象的声明周期内,它所管理的锁对象会一直保持上锁状态;而 lock_guard 的生命周期结束之后,它所管理的锁对象会被解锁(注:类似 shared_ptr 等智能指针管理动态分配的内存资源 )。
值得注意的是,lock_guard 对象并不负责管理 Mutex 对象的生命周期,lock_guard 对象只是简化了 Mutex 对象的上锁和解锁操作,方便线程对互斥量上锁,即在某个 lock_guard 对象的声明周期内,它所管理的锁对象会一直保持上锁状态;而 lock_guard 的生命周期结束之后,它所管理的锁对象会被解锁。
特点:
- 创建即加锁,作用域结束自动析构并解锁,无需手工解锁
- 不能中途解锁,必须等作用域结束才解锁
- 不能复制
unique_lock
虽然lock_guard挺好用的,但是有个很大的缺陷,在定义lock_guard的地方会调用构造函数加锁,在离开定义域的话lock_guard就会被销毁,调用析构函数解锁。这就产生了一个问题,如果这个定义域范围很大的话,那么锁的粒度就很大,很大程序上会影响效率。
lock_guard最大的缺点也是简单,没有足够的灵活度。
unique_lock 对象以独占所有权的方式( unique owership)管理 mutex 对象的上锁和解锁操作,所谓独占所有权,就是没有其他的 unique_lock 对象同时拥有某个 mutex 对象的所有权。
和 lock_guard 一样,这也是一种简单而又安全的上锁和解锁方式,尤其是在程序抛出异常后先前已被上锁的 Mutex 对象可以正确进行解锁操作,极大地简化了程序员编写与 Mutex 相关的异常处理代码。
- unique_lock可以实现延时锁,即先生成unique_lock对象,然后在有需要的地方调用lock函数,lock_guard在对象创建时就自动进行lock操作了;
- unique_lock可以在需要的地方调用unlock操作,而lock_guard只能在其对象生命周期结束后自动Unlock;
Reference
[1] https://zhuanlan.zhihu.com/p/340154702
[2] https://blog.csdn.net/zzhongcy/article/details/85230200
[3] https://zhuanlan.zhihu.com/p/340348726
[4] https://www.jianshu.com/p/b67cc7b40a1e
网友评论