我在C++17
中遇到std::shared_mutex
。 std::shared_mutex
究竟是什麼,它與std::mutex
有什麼不同?std :: mutex和std :: shared_mutex之間的區別
回答
指出的shared_mutex類是原始的同步可以被用來保護從由多個線程同時被訪問的共享數據。與此相反,以有利於獨佔訪問其他的互斥鎖類型,一個shared_mutex有兩級訪問:
- 共享 - 多個線程可以共享相同的互斥的所有權。
- 排他 - 只有一個線程可以擁有該互斥量。
共享互斥鎖通常用於多個讀取器可以同時訪問同一資源但不會導致數據競爭的情況,但只有一個寫入器可以這樣做。
這有多種用途,但一個共同的一個是實現Read Write Lock在那裏你可以有多個線程讀取共享數據,但只有一個線程專門在任何時間寫作。所以當你有多個讀卡器時,互斥鎖會以「共享模式」工作,但是當請求寫入時,它會變成「獨佔模式」。
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
是一個典型的讀寫互斥,因爲它允許 兩種不同的用法:由單一的「作家」線程獨佔訪問或共享,通過多 併發訪問「讀者「線程。
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); }
};
- 1. std :: logical_not和std :: not1之間的區別?
- 2. std :: is_integer和std :: is_integral之間的區別?
- 3. std :: regex_match和std :: regex_search之間的區別?
- 4. std :: uninitialized_copy和std :: copy之間的區別?
- 5. std :: unique_lock <std::mutex>或std :: lock_guard <std::mutex>?
- 6. C++ std :: mutex與windows之間有什麼區別CreateMutex
- 7. vector :: begin()和std :: begin()之間的區別
- 8. std :: endl和\ n之間的區別
- 9. std :: exception和「...」之間的區別
- 10. std :: result_of和decltype之間的區別
- 11. std :: array和boost :: array之間的區別
- 12. '-std'和'--std'編譯器標記之間的區別
- 13. std :: string name和std :: string&name之間的C++區別
- 14. C++ std :: lock和std :: unique_lock之間有什麼區別?
- 15. std :: strtol和std :: stoi之間有什麼區別?
- 16. std :: condition_variable和std :: condition_variable_any之間有什麼區別?
- 17. -std = C++ 11和-std = gnu ++ 11之間有什麼區別?
- 18. 什麼更好std :: lock_guard <std::mutex>鎖(std :: mutex mutex_var);或std :: mutex mutex_var.lock();
- 19. std :: forward實現之間的區別
- 20. boost :: mutex和boost :: timed_mutex之間的區別
- 21. 使用std :: thread與std :: mutex
- 22. C++中std :: unique_ptr和std :: shared_ptr的區別
- 23. std :: transform和std :: for_each有什麼區別?
- 24. std :: function和std :: mem_fn有什麼區別
- 25. std :: invoke和std :: function有什麼區別?
- 26. std :: set和std :: vector有什麼區別?
- 27. std :: cout和std :: wcout有什麼區別?
- 28. std :: merge和std :: set_union有什麼區別?
- 29. std :: partial_sum和std :: inclusive_scan有什麼區別?
- 30. 區別:std :: runtime_error vs std :: exception()