简体   繁体   English

shared_mutex锁定顺序

[英]shared_mutex lock ordering

I was under the impression a multiple reader / single writer pattern implemented with c++17's std::shared_mutex could potentially never relinquish unique locks if too many shared locks were acquired. 我的印象是,如果获得了太多的共享锁,那么使用c ++ 17的std::shared_mutex实现的多个读者/单个编写器模式可能永远不会放弃唯一锁。

After digging on cppreference , I am unsure that is the case. 在挖掘cppreference之后 ,我不确定是这样的。 Specifically : 特别是:

All lock and unlock operations on a single mutex occur in a single total order 单个互斥锁上的所有锁定和解锁操作都在一个总订单中进行

For example, given the following operations on a shared_mutex , I believed the unique_lock may never acquire. 例如,给定shared_mutex上的以下操作,我相信unique_lock可能永远不会获取。 Assuming an infinite amount of shared_locks , and that these locks acquire before the first shared_locks release. 假设shared_locks限量的shared_locks ,并且这些锁在第一个shared_locks发布之前获取。

shared_lock
shared_lock
shared_lock

unique_lock

shared_lock
[...]
shared_lock

Giving the following characteristics. 具有以下特点。

{ shared_lock, shared_lock, shared_lock, shared_lock, ..., shared_lock } // never releases

unique_lock

However, if I understand cppreference correctly, once the unique_lock tries to acquire, consecutive shared_locks would block until the unique_lock is released. 但是,如果我正确理解cppreference,一旦unique_lock尝试获取,连续的shared_locks将阻塞,直到unique_lock被释放。 Giving the following threading characteristics. 给出以下线程特征。

{ shared_lock, shared_lock, shared_lock} // simultaneous

unique_lock

{ shared_lock, ..., shared_lock} // waits, then simultaneous

So my question is, does a std::shared_mutex keep ordering between shared and unique locks? 所以我的问题是, std::shared_mutex在共享锁和唯一锁之间保持排序? Preventing the case where unique_locks are never acquired due to an overwhelming amount of shared_locks being acquired. 防止由于获取了大量的shared_locks而永远不会获取unique_locks的情况。

edit : 编辑:

Here is a code example to help understand the problem, and for posterity's sake. 这是一个帮助理解问题的代码示例,为了后人的缘故。 On MSVC 2019, shared_mutex is safe and ordering happens as desired. 在MSVC 2019上, shared_mutex是安全的,并且根据需要进行排序。 The unique_lock does get processed before the "infinite" amount of shared_locks . unique_lock确实在“无限”数量的shared_locks之前得到处理。

The question now becomes, is this platform dependent? 现在的问题是,这个平台是否依赖?

#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();
    }
}

Outputs : 产出:

read
read
read
write
read
...
read

The std shared_mutex specification does not specify a priority for shared locks nor unique locks. std shared_mutex规范未指定共享锁的优先级,也不指定唯一锁。 Nor is there any API to set such a priority. 也没有任何API可以设置这样的优先级。 One of the original motivations for the lack of specification for priority is the existence of the Alexander Terekhov algorithm as explained here . 缺乏优先权规范的原始动机之一是存在如此处所解释Alexander Terekhov算法

A secondary motivation is to explain the lack of reader-writer priority policies in shared_mutex. 第二个动机是解释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. 这是由于算法归功于Alexander Terekhov,它让操作系统决定下一个获得锁定的线程,而不关心是否正在寻找一个独特的锁或共享锁。 This results in a complete lack of reader or writer starvation. 这导致完全缺乏读者或作家的饥饿。 It is simply fair. 这很公平。

The standard spec does not require the Alexander Terekhov algorithm. 标准规范不需要Alexander Terekhov算法。 However it was at least my hope, that this algorithm would be preferred because of the lack of specification or API for preferring readers over writers or vice-versa. 然而,至少我希望,这种算法将是首选,因为缺乏规范或API优先于读者而不是编写者,反之亦然。

There are more details about the Alexander Terekhov algorithm and some code which demonstrates its behavior in this SO answer here . 有关Alexander Terekhov算法的更多细节以及一些代码,这些代码在此SO答案中展示了它的行为。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 std :: lock()是否等同于boost :: shared_mutex? - std::lock() equivalent for boost::shared_mutex? 错误:使用ReaderLock = std :: shared_lock的&#39;shared_mutex&#39;不是&#39;std&#39;的成员 <std::shared_mutex> ; - error: ‘shared_mutex’ is not a member of ‘std’ using ReaderLock = std::shared_lock<std::shared_mutex>; scoped_lock可以在读模式下锁定shared_mutex吗? - Can scoped_lock lock a shared_mutex in read mode? std::shared_mutex 不与执行 lock_shared() 的线程一起缩放 - std::shared_mutex not scaling with threads doing lock_shared() 什么时候使用unique_lock与shared_mutex? - At what point to use unique_lock with shared_mutex? 无法将参数1从&#39;const boost :: shared_mutex&#39;转换为&#39;const boost :: shared_lock <Mutex> &” - cannot convert parameter 1 from 'const boost::shared_mutex' to 'const boost::shared_lock<Mutex> &' BOOST:递归shared_mutex? - BOOST: recursive shared_mutex? 错误:没有匹配函数调用&#39;boost :: shared_lock <boost::shared_mutex> :: shared_lock(const Lock&)&#39; - error: no matching function for call to 'boost::shared_lock<boost::shared_mutex>::shared_lock(const Lock&)' 带有std :: shared_lock的std :: shared_mutex是读者还是作家更喜欢? - std::shared_mutex with std::shared_lock is reader or writer preferring? 我可以在 std::shared_mutex 上使用 std::shared_lock 更改数据吗? - Can I change data with a std::shared_lock on a std::shared_mutex?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM