使用方式
lock_guard:通过构造函数和析构函数控制锁的作用范围,创造对象的时候加锁,离开作用域的时候解锁;
std::mutex m_mutex;
void print(int cnt)
{
std::lock_guard<mutex> lock(m_mutex);
cout << std::this_thread::get_id() << " " << cnt << endl;
}
unique_lock:可以通过构造函数和析构函数控制锁的作用范围,也可以在构造函数中延时加锁,在需要的时候手动加锁和解锁。
std::mutex m_mutex;
void print(int cnt)
{
//用unique_lock来对锁进行管理.defer_lock是它的构造参数之一.用来推迟加锁.
unique_lock<mutex> lock(m_mutex, defer_lock);
/*
...这里可以进行一系列线程安全的操作...
*/
//手动加锁.
lock.lock();
cout << std::this_thread::get_id() << " " << cnt << endl;
lock.unlock();
//这里用来计算sum的值.然后打印.因为sum是在函数内定义的局部变量.所以下面的代码是线程安全的.没必要用锁对这段代码进行保护.所以在上面用unlock解锁.
int sum = 0;
for (int i = 0; i < cnt; ++i)
{
sum += i;
}
//最后在手动加锁.不用手动释放.因为会在生命周期结束时自动释放.
lock.lock();
cout << std::this_thread::get_id() << " " << sum << endl;
}
赋值操作
lock_guard不支持赋值操作。unique_lock支持可移动赋值,若占有互斥量则解锁互斥,并取得另一者的所有权
资源消耗
unique_lock相对而言更加灵活,对于资源的消耗明显要大一些,因为它要维持mutex的状态;
lock_guard虽然笨重一些,但是资源消耗相对要小一点。