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_lock<boost::mutex>的typedef,在C++11中已經禁用。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM