gpt4 book ai didi

c++ - shared_mutex 锁排序

转载 作者:可可西里 更新时间:2023-11-01 18:38:53 32 4
gpt4 key购买 nike

我的印象是,如果获取了太多共享锁,使用 c++17 的 std::shared_mutex 实现的多读/单写模式可能永远不会放弃唯一锁。

cppreference 上挖掘之后,我不确定情况是否如此。具体来说:

All lock and unlock operations on a single mutex occur in a single total order

例如,给定以下对 shared_mutex 的操作,我相信 unique_lock 可能永远不会获得。假设无限量的 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 algorithm as explained here 的存在。 .

A secondary motivation is to explain the lack of reader-writer priority policies in shared_mutex. This is due to an algorithm credited to Alexander Terekhov which lets the OS decide which thread is the next to get the lock without caring whether a unique lock or shared lock is being sought. This results in a complete lack of reader or writer starvation. It is simply fair.

标准规范不需要 Alexander Terekhov 算法。然而,至少我希望这种算法会更受欢迎,因为缺乏规范或 API 来优先考虑读者而不是作者,反之亦然。

this SO answer here 中有更多关于 Alexander Terekhov 算法和演示其行为的代码的详细信息。 .

关于c++ - shared_mutex 锁排序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56091709/

32 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com