2017-09-27 256 views

回答

6

the documentation

指出的shared_mutex類是原始的同步可以被用來保護從由多個線程同時被訪問的共享數據。與此相反,以有利於獨佔訪問其他的互斥鎖類型,一個shared_mutex有兩級訪問:

  • 共享 - 多個線程可以共享相同的互斥的所有權。
  • 排他 - 只有一個線程可以擁有該互斥量。

共享互斥鎖通常用於多個讀取器可以同時訪問同一資源但不會導致數據競爭的情況,但只有一個寫入器可以這樣做。

這有多種用途,但一個共同的一個是實現Read Write Lock在那裏你可以有多個線程讀取共享數據,但只有一個線程專門在任何時間寫作。所以當你有多個讀卡器時,互斥鎖會以「共享模式」工作,但是當請求寫入時,它會變成「獨佔模式」。

1

std::shared_mutex可能是有用的,尤其是在數據結構(如DNS緩存)獲取很少更新的情況下。使用std::mutex來保護數據結構可能過於悲觀,因爲它消除了在未經修改時讀取數據結構 時可能的併發性。多個線程可以同時在同一std::shared_mutex上共享一個鎖。從安東尼·威廉斯書

一個這樣的例子:

class dns_cache 
{ 
    std::map<std::string,dns_entry> entries; 
    mutable boost::shared_mutex entry_mutex; 

public: 

    dns_entry find_entry(std::string const& domain) const 
    { 
     boost::shared_lock<boost::shared_mutex> lk(entry_mutex); 
     std::map<std::string,dns_entry>::const_iterator const it = entries.find(domain); 
     return (it==entries.end()) ? dns_entry() : it->second; 
    } 

    void update_or_add_entry(std::string const& domain, 
          dns_entry const& dns_details) 
    { 
     std::lock_guard<boost::shared_mutex> lk(entry_mutex); 
     entries[domain] = dns_details; 
    } 
}; 

這裏,功能find_entry基本上沒有讀操作,而update_or_add_entry執行寫操作。

所以,可以說,std::shared_mutex是一個典型的讀寫互斥,因爲它允許 兩種不同的用法:由單一的「作家」線程獨佔訪問或共享,通過多 併發訪問「讀者「線程。

0

A mutex被鎖定或不鎖定。

A shared_mutex要麼被鎖定,要麼被鎖定共享,或者不被鎖定。

任何數量的客戶端都可以共享鎖定一個共享互斥鎖。

如果有人把它獨佔鎖定,沒有其他人可以持有任何鎖。

在windows上,這是SWRLOCK類型 - 事實上,此鎖通常用於實現讀寫鎖;許多讀者允許,但寫作必須是排他性的。

以下是一些示例代碼,用於爲共享和非共享互斥創建兩個模板包裝。在一種情況下,我們有讀取和寫入操作獲得不同的鎖。另一方面,我們只需訪問:

template<class T, class M=std::mutex> 
struct mutex_guarded { 
    template<class F> 
    auto access(F&& f) { 
    auto l = lock(); 
    return std::forward<F>(f)(t); 
    } 
    template<class F> 
    auto access(F&& f) const { 
    auto l = lock(); 
    return std::forward<F>(f)(t); 
    } 
    mutex_guarded(mutex_guarded const&)=delete; 
    mutex_guarded& operator=(mutex_guarded const&)=delete; 
    template<class...Ts> 
    mutex_guarded(Ts&&...ts):t(std::forward<Ts>(ts)...){} 
    mutex_guarded()=default; 
protected: 
    mutable M m; 
    T t; 
    auto lock() { return std::unique_lock<M>(m); } 
}; 
template<class T, class M=std::shared_mutex> 
struct shared_mutex_guarded:private mutex_guarded<T, M> { 
    using base = mutex_guarded<T, M>; 
    template<class F> 
    auto read(F&& f) const { return access(std::forward<F>(f)); } 
    template<class F> 
    auto write(F&& f) { return access(std::forward<F>(f)); } 

    using base::base; 
protected: 
    using base::access; 
    template<class F> 
    auto access(F&& f) const { 
    auto l = lock(); 
    return std::forward<F>(f)(this->t); 
    } 
    using base::lock; 
    auto lock() const { return std::shared_lock<M>(this->m); } 
}; 
相關問題