[英]shared_mutex lock ordering
我的印象是,如果獲得了太多的共享鎖,那么使用c ++ 17的std::shared_mutex
實現的多個讀者/單個編寫器模式可能永遠不會放棄唯一鎖。
在挖掘cppreference之后 ,我不確定是這樣的。 特別是:
單個互斥鎖上的所有鎖定和解鎖操作都在一個總訂單中進行
例如,給定shared_mutex
上的以下操作,我相信unique_lock
可能永遠不會獲取。 假設shared_locks
限量的shared_locks
,並且這些鎖在第一個shared_locks
發布之前獲取。
shared_lock
shared_lock
shared_lock
unique_lock
shared_lock
[...]
shared_lock
具有以下特點。
{ shared_lock, shared_lock, shared_lock, shared_lock, ..., shared_lock } // never releases
unique_lock
但是,如果我正確理解cppreference,一旦unique_lock
嘗試獲取,連續的shared_locks
將阻塞,直到unique_lock
被釋放。 給出以下線程特征。
{ shared_lock, shared_lock, shared_lock} // simultaneous
unique_lock
{ shared_lock, ..., shared_lock} // waits, then simultaneous
所以我的問題是, std::shared_mutex
在共享鎖和唯一鎖之間保持排序? 防止由於獲取了大量的shared_locks
而永遠不會獲取unique_locks
的情況。
編輯:
這是一個幫助理解問題的代碼示例,為了后人的緣故。 在MSVC 2019上, shared_mutex
是安全的,並且根據需要進行排序。 unique_lock
確實在“無限”數量的shared_locks
之前得到處理。
現在的問題是,這個平台是否依賴?
#include <chrono>
#include <cstdio>
#include <mutex>
#include <shared_mutex>
#include <thread>
#include <vector>
using namespace std::chrono_literals;
std::shared_mutex smtx;
int main(int, char**) {
std::vector<std::thread> threads;
auto read_task = [&]() {
std::shared_lock l{ smtx };
printf("read\n");
std::this_thread::sleep_for(1s);
};
auto write_task = [&]() {
std::unique_lock l{ smtx };
printf("write\n");
std::this_thread::sleep_for(1s);
};
// Create a few reader tasks.
threads.emplace_back(read_task);
threads.emplace_back(read_task);
threads.emplace_back(read_task);
// Try to lock a unique_lock before read tasks are done.
std::this_thread::sleep_for(1ms);
threads.emplace_back(write_task);
// Then, enque a gazillion read tasks.
// Will the unique_lock be locked? [drum roll]
// Would be while(true), 120 should be enough for demo
for (size_t i = 0; i < 120; ++i) {
std::this_thread::sleep_for(1ms);
threads.emplace_back(read_task);
}
for (auto& t : threads) {
t.join();
}
}
產出:
read
read
read
write
read
...
read
std shared_mutex
規范未指定共享鎖的優先級,也不指定唯一鎖。 也沒有任何API可以設置這樣的優先級。 缺乏優先權規范的原始動機之一是存在如此處所解釋的Alexander Terekhov算法 。
第二個動機是解釋shared_mutex中缺少讀寫器優先級策略。 這是由於算法歸功於Alexander Terekhov,它讓操作系統決定下一個獲得鎖定的線程,而不關心是否正在尋找一個獨特的鎖或共享鎖。 這導致完全缺乏讀者或作家的飢餓。 這很公平。
標准規范不需要Alexander Terekhov算法。 然而,至少我希望,這種算法將是首選,因為缺乏規范或API優先於讀者而不是編寫者,反之亦然。
有關Alexander Terekhov算法的更多細節以及一些代碼,這些代碼在此SO答案中展示了它的行為。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.