C++11中lock_guard和unique_lock的特点和区别,condition_variable为何搭配unique_lock使用

lock_guard

template<typename _Mutex>
    class lock_guard
    {
    public:
      typedef _Mutex mutex_type;
      explicit lock_guard(mutex_type& __m) : _M_device(__m)
      { _M_device.lock(); }
      
      ~lock_guard()
      { _M_device.unlock(); }

      lock_guard(const lock_guard&) = delete;
      lock_guard& operator=(const lock_guard&) = delete;
    private:
      mutex_type&  _M_device;
    };
  1. 构造函数中自动获取锁,析构函数中自动释放锁;
  2. 将拷贝构造函数和赋值运算符重载函数delete掉了,也就是说lock_guard将 不能做为函数参数传递或者函数的返回值
  3. 使用了智能指针的思想,出作用域自动释放锁。

unique_lock

  template<typename _Mutex>
    class unique_lock
    {
    public:
      typedef _Mutex mutex_type;

unique_lock() noexcept
      : _M_device(0), _M_owns(false){}

explicit unique_lock(mutex_type& __m)
      : _M_device(std::__addressof(__m)), _M_owns(false)
      {
		lock();
		_M_owns = true;
      }

~unique_lock()
      {
	if (_M_owns)
	  unlock();
      }

//同样删除了带左值的拷贝构造函数和赋值运算符重载函数
unique_lock(const unique_lock&) = delete;
unique_lock& operator=(const unique_lock&) = delete;
      
//但是添加了带右值的拷贝构造函数和赋值运算符重载函数
unique_lock(unique_lock&& __u) noexcept
      : _M_device(__u._M_device), _M_owns(__u._M_owns)
      {
		__u._M_device = 0;
		__u._M_owns = false;
      }

unique_lock& operator=(unique_lock&& __u) noexcept
      {
		if(_M_owns)
	  	unlock();
		unique_lock(std::move(__u)).swap(*this);
		__u._M_device = 0;
		__u._M_owns = false;
		return *this;
      }

void lock()
      {
		if (!_M_device)
	  	__throw_system_error(int(errc::operation_not_permitted));
		else if (_M_owns)
	  	__throw_system_error(int(errc::resource_deadlock_would_occur));
		else
	  {
	    _M_device->lock();
	    _M_owns = true;
	  }
      }

void unlock()
      {
		if (!_M_owns)
	  	__throw_system_error(int(errc::operation_not_permitted));
		else if (_M_device)
	  	{
	    	_M_device->unlock();
	    	_M_owns = false;
	 	 }
      	}

    private:
      mutex_type*	_M_device;
      bool		_M_owns;
    };
  1. 同样也是构造函数中获取锁,析构函数中释放锁;
  2. 同样删除了带左值的拷贝构造函数和赋值运算符重载函数
  3. 但是新增了带右值引用参数的拷贝构造函数和赋值运算符重载函数,这就使得unique_lock可以在函数传参或者参数返回中使用该锁
  4. 提供了lock()和unlock()方法,才可以与条件变量condition_variable搭配使用。
#include <condition_variable>
#include <mutex>

std::condition_variable cdv_;
std::mutex mtx_;

std::unique_lock<std::mutex> lck(mtx_);

cdv_.wait(lck);

这里的wait()做了俩件事情:

  1. 把当前的线程置为睡眠状态,可能因为自身执行的条件不满足,如资源不足等;
  2. 调用lck的unlock()方法,将锁mtx_释放掉,这样才能让其他线程获取lock()到锁,占用cpu.

最后补充一个条件变量接口:

cdv_.notify_all();
cdv_.notify_one();
  1. 唤醒等待在cdv_上的所有的线程,然后再去获取该条件变量上的锁,获取到的继续执行
  2. 唤醒等待在cdv_上的一个线程,再去获取该条件变量上的锁,获取到继续执行
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值