沒有得到一個在線示例來生動地演示這一點。在http://en.cppreference.com/w/cpp/header/shared_mutex上看到一個例子說明了一個例子,但是 仍然不清楚。有人可以幫忙嗎?共享互斥和互斥之間的區別(爲什麼都存在於C++ 11併發中)?
回答
「共享互斥鎖通常用於多個讀者可以同時訪問同一資源而不引起數據競爭的情況,但只有一個作者可以這樣做。」
cppreference.com
當你需要讀取/寫入器鎖這是有用的:https://en.wikipedia.org/wiki/Readers%E2%80%93writer_lock
是的,我只有線程可以同時讀取數據嗎?爲什麼讀者需要鎖?只有修改需要鎖定才能使底層的數據結構不被破壞? –
@AnandKulkarni讀者需要鎖定,否則他們可能會讀取數據,而另一個線程正在寫入相同的數據。這是爲了防止數據競爭。通過讀取/寫入器鎖定,多個讀取器可以同時訪問數據。 – 0xBADF00
通過使用正常互斥的,你能保證某種關鍵資源的獨佔訪問 - 而不是其他。共享互斥通過允許訪問的兩級延伸此功能:共享和獨佔如下:
- 獨佔訪問防止任何其它線程獲取該互斥,正如與正常的互斥。其他線程是否嘗試獲取共享或獨佔訪問權限並不重要。
- 共享訪問允許多個線程獲取互斥量,但是所有的只能在共享模式下使用。直到所有先前的共享持有者已經返回互斥量爲止,纔會授予獨佔訪問權限(通常,只要獨佔請求正在等待,新共享對象在之後排隊等待授予)。
一個典型的場景是數據庫:多個線程同時讀取一個數據和同一個數據並不重要。但修改數據庫至關重要 - 如果某個線程正在讀取數據,而另一個線程正在寫入數據,則可能會收到不一致的數據。所以所有的閱讀必須完成才能書寫,新的閱讀必須等到寫作完成。寫入後,可能會再次同時發生進一步的讀取。
編輯:旁註:
爲什麼讀者需要的鎖?
這是爲了防止作者在讀取過程中獲取鎖而發生。此外,它還可以防止新讀者在專門持有鎖的情況下獲得鎖。
非常清楚的理解,我們不希望讀者在修改正在發生時讀取陳舊的數據,反之亦然,因爲目前正在進行讀取,所以我們不希望作者開始進行更改以保持數據一致 –
共享互斥鎖有兩個訪問級別'shared'和'exclusive'。 多個線程可以獲得共享訪問權限,但只有一個可以擁有「獨佔」訪問權限(包括沒有共享訪問權限)。
常見的情況是讀/寫鎖。回想一下Data Race只能在兩個線程訪問相同的數據時發生其中至少有一個是寫。
利用這些數據可能會被許多讀者讀取,但是當作者需要訪問時,他們必須獲得數據的獨佔訪問權。
下面是一個示例(稍後從示例http://en.cppreference.com/w/cpp/thread/shared_mutex稍微改編)。
#include <iostream>
#include <mutex> // For std::unique_lock
#include <shared_mutex>
#include <thread>
std::mutex cout_mutex;
void log(const std::string& msg){
std::lock_guard guard(cout_mutex);
std::cout << msg << std::endl;
}
class ThreadSafeCounter {
public:
ThreadSafeCounter() = default;
// Multiple threads/readers can read the counter's value at the same time.
unsigned int get() const {
std::shared_lock lock(mutex_);//NB: std::shared_lock will shared_lock() the mutex.
log("get()-begin");
std::this_thread::sleep_for(std::chrono::milliseconds(500));
auto result=value_;
log("get()-end");
return result;
}
// Only one thread/writer can increment/write the counter's value.
void increment() {
std::unique_lock lock(mutex_);
value_++;
}
// Only one thread/writer can reset/write the counter's value.
void reset() {
std::unique_lock lock(mutex_);
value_ = 0;
}
private:
mutable std::shared_mutex mutex_;
unsigned int value_ = 0;
};
int main() {
ThreadSafeCounter counter;
auto increment_and_print = [&counter]() {
for (int i = 0; i < 3; i++) {
counter.increment();
auto ctr=counter.get();
{
std::lock_guard guard(cout_mutex);
std::cout << std::this_thread::get_id() << ' ' << ctr << '\n';
}
}
};
std::thread thread1(increment_and_print);
std::thread thread2(increment_and_print);
std::thread thread3(increment_and_print);
thread1.join();
thread2.join();
thread3.join();
}
可能的部分輸出:
get()-begin
get()-begin
get()-end
140361363867392 2
get()-end
140361372260096 2
get()-begin
get()-end
140361355474688 3
//Etc...
通知如何兩個get()-begin()
返回顯示,兩個線程的讀取期間保持共享鎖。
- 1. 在模塊之間共享互斥體
- 2. 在什麼有增強共享互斥
- 3. 互斥鎖與pthread_join之間的區別
- 4. C++ 11間原子學和互斥
- 5. 爲什麼互斥體不需要互斥體(並且該互斥體需要互斥體...)
- 6. C++共享互斥量和類實例的11個線程
- 7. 地圖互斥C++ 11
- 8. 互斥或不互斥互斥?
- 9. 在C++ 98互斥鎖中鎖定變量共享數據互斥鎖
- 10. C++ - 進程之間共享的互斥體
- 11. 共享內存併發算法與互斥鎖/信號量之間的關係
- 12. 讀寫之間的互斥
- 13. 鎖,互斥和臨界區之間的區別
- 14. 互斥體和臨界區之間的邊界是什麼?
- 15. boost進程間共享互斥和boost進程間條件變量共享互斥
- 16. 條件變量和共享互斥
- 17. 互斥和同步的區別?
- 18. 在C++中處理互斥11
- 19. 共享互斥鎖的交替例程
- 20. 信號量和互斥量在實現中有什麼區別?
- 21. 互斥並行
- 22. C++中互斥鎖和臨界區之間的性能差異
- 23. 寫一個互斥的共享資源
- 24. Java中互斥線程的互斥量?
- 25. 互斥C#。如何系統識別互斥碼
- 26. pthread進程共享互斥死鎖
- 27. boost :: asio鏈vs共享互斥的
- 28. 互斥和條件變量之間的決定性區別是什麼?
- 29. C++ 14 shared_timed_mutex VS C++ 11互斥體
- 30. iPhone上的「互斥」和NSCondition的共享內存
您應該查看[documentation](http://en.cppreference.com/w/cpp/thread/shared_mutex)而不是標題摘要(如鏈接所示)。順便說一句,這是C++ 17而不是C++ 11。最接近的是C++ 14,它是'std :: shared_timed_mutex'。儘管如此,你有沒有聽說過[讀者 - 作家鎖定](https://en.wikipedia.org/wiki/Readers%E2%80%93writer_lock)? – WhiZTiM