boost::unique_lock和boost::lock_guard的区别

lock_guard

boost::mutex mutex;  
boost::lock_guard<boost::mutex> lock(mutex);

unique_lock

boost::mutex mutex;  
boost::unique_lock<boost::mutex> lock(mutex);

std::unique_lock 与std::lock_guard都能实现自动加锁与解锁功能,但是std::unique_lock要比std::lock_guard更灵活,但是更灵活的代价是占用空间相对更大一点且相对更慢一点。

通过实现一个线程安全的队列来说明两者之间的差别。

template <typename T>
class ThreadSafeQueue{
public:
         void Insert(T value);
         void Popup(T &value);
         bool Empety();

private:
       mutable std::mutex mut_;
       std::queue<T> que_;
       std::condition_variable cond_;
};
template <typename T>
void ThreadSafeQueue::Insert(T value){
    std::lock_guard<std::mutex> lk(mut_);
    que_.push_back(value);
    cond_.notify_one();
}


template <typename T>
void ThreadSafeQueue::Popup(T &value){
    std::unique_lock<std::mutex> lk(mut_);//lambda表达式,是一种匿名函数。方括号内表示捕获变量。//当lambda表达式返回true时(即queue不为空),wait函数会锁定mutex。//当lambda表达式返回false时,wait函数会解锁mutex同时会将当前线程置于阻塞或等待状态。
    cond_.wait(lk, [this]{return !que_.empety();});
    value = que_.front();
    que_.pop();
}


template <typename T>
bool ThreadSafeQueue::Empty() const{
        std::lock_guard<std::mutex> lk(mut_);
        return que_.empty();
}

上面代码只实现了关键的几个函数,并使用了C++11新引入的condition_variable条件变量。从Popup与Inert两个函数看std::unique_lock相对std::lock_guard更灵活的地方在于在等待中的线程如果在等待期间需要解锁mutex,并在之后重新将其锁定。而std::lock_guard却不具备这样的功能。

  • 如果只是为了保证数据同步,那么lock_guard完全够用;
  • 如果除了同步,还需要使用condition进行阻塞时,那么就需要用unique_lock

    • std::unique_lock相对std::lock_guard更灵活的地方在于在等待中的线程如果在等待期间需要解锁mutex,并在之后重新将其锁定。而std::lock_guard却不具备这样的功能。
  • boost还要一个boost::mutex::scoped_lock,这个是boost::unique_locktypedef,在C++11中已经禁用。
    原文链接: https://www.cnblogs.com/zhanghu52030/p/9166979.html

欢迎关注

微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍

原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/275790

非原创文章文中已经注明原地址,如有侵权,联系删除

关注公众号【高性能架构探索】,第一时间获取最新文章

转载文章受原作者版权保护。转载请注明原作者出处!

(0)
上一篇 2023年2月15日 上午1:15
下一篇 2023年2月15日 上午1:16

相关推荐