C++11多线程unique_lock与lock_guard
lock_guard:
- 一个互斥量包装程序,提供了一种RAII风格的机制来再作用域块的持续时间内拥有一个互斥量;
 - 创建该对象时,它会去获取提供给它的互斥锁的所有权,当控制流离开该对象作用域时,lock_guard析构并释放互斥量。
 - lock_guard本身并没有提供加锁和解锁的接口(实际存在需求,只能保证在析构的时候释放锁。
 - 不能复制。
 
unique_lock:
- 也是一个互斥量的包装程序;
 - 允许延迟锁定,显示深度锁定,递归锁定,锁定所有权转移,和条件变量一起使用;
 - 提供了
lock()和unlock()接口,在析构的时候,会根据当前状态来决定是否要进行解锁。 - 不能复制,但能移动。
 
使用lock_guard就需要创建两个局部对象来管理同一个互斥锁。
1 class LogFile { 2 std::mutex _mu; 3 ofstream f; 4 public: 5 LogFile() { 6 f.open("log.txt"); 7 } 8 ~LogFile() { 9 f.close(); 10 } 11 void shared_print(string msg, int id) { 12 { 13 std::lock_guard<std::mutex> guard(_mu); 14 //do something 1 15 } 16 //do something 2 17 { 18 std::lock_guard<std::mutex> guard(_mu); 19 // do something 3 20 f << msg << id << endl; 21 cout << msg << id << endl; 22 } 23 } 24 25 };
如下面代码显示,unique_lock可以灵活控制上锁和释放,这样避免重复的实例化lock_guard对象,还能减少锁的区域。(可以使用std::defer_lock设置初始化的时候不进行默认的上锁操作)
1 void shared_print(string msg, int id) { 2 std::unique_lock<std::mutex> guard(_mu, std::defer_lock); 3 //do something 1 4 5 guard.lock(); 6 // do something protected 7 guard.unlock(); //临时解锁 8 9 //do something 2 10 11 guard.lock(); //继续上锁 12 // do something 3 13 f << msg << id << endl; 14 cout << msg << id << endl; 15 // 结束时析构guard会临时解锁 16 }
C++11中的unique_lock使用起来要比lock_guard更灵活,但是效率会低,内存的占用也会大。unique_lock也是一个类模板,但是比起lock_guard,它通过自己的成员函数来更加灵活进行锁的操作。
                    
                
                
            
        
浙公网安备 33010602011771号