【问题标题】:Can a shared lock on a std::shared_timed_mutex be upgraded to an exclusive lock?std::shared_timed_mutex 上的共享锁可以升级为独占锁吗?
【发布时间】:2014-08-11 15:39:16
【问题描述】:

新的 std::shared_timed_mutex 允许两种类型的锁:共享锁和排他锁。

如果一个人持有共享锁,有没有办法将它原子交换(“升级”)为独占锁?换句话说,给定以下代码,我怎样才能避免非原子丢弃和重新锁定?

std::shared_timed_mutex m; //Guards a std::vector.
m.lock_shared();

//Read from vector. (Shared lock is sufficient.)
// ...

//Now we want to write to the vector. We need an exclusive lock.
m.unlock_shared();
                   //     <---- Problem here: non-atomic! 
m.lock(); 

//Write to vector.
// ...

m.unlock();

理想情况下,m.unlock_shared(); m.lock(); 可以替换为类似 m.upgrade_to_exclusive();(或类似 boost::.upgrade_to_unique_lock())的内容。

In a similar question but for Boost's shared_mutexDave S 提到

如果不先释放共享锁,就不可能从共享锁转换为唯一锁,或从共享锁转换为可升级锁。

我不确定这是否适用于 std::shared_mutex,尽管我怀疑它确实如此。

我会对基于 std::atomic/condition_variable 或 GCC 事务内存的合理解决方法感到满意。

编辑:霍华德的回答解决了我的问题。他的proposal N3427 包含对实现互斥升级的机制的很好描述。我仍然欢迎基于 std::atomic/condition_variable 或 GCC 事务内存的变通方法。

【问题讨论】:

标签: c++ multithreading c++11 c++14


【解决方案1】:

不,它不能。该功能以upgrade_mutexupgrade_lock 的名义向委员会提出,但委员会选择拒绝该部分提案。目前没有任何工作可以重新设置该功能。

编辑

针对 user3761401 的问题中的“从这里去哪里”编辑,我在这里创建了一个部分瘫痪的 upgrade_mutex/upgrade_lock 实现:

https://github.com/HowardHinnant/upgrade_mutex

请随意使用。它在公共领域。它只是经过轻微测试,不具备N3427 中描述的全部功能。特别是缺少以下功能:

  • 无法将unique_lock 转换为shared_timed_lock
  • 无法尝试或定时将shared_timed_lock 转换为unique_lock
  • 无法尝试或定时将upgrade_lock 转换为unique_lock

话虽如此,我已经在upgrade_mutex 中包含了这个功能,并且可以在这个低级别以非常丑陋的方式访问它(这样的例子在 main.cpp 中)。

N3427 中提到的其他锁转换可用。

  • shared_timed_lockupgrade_lock 的尝试和定时转换。
  • upgrade_lock 转换为shared_timed_lock
  • 阻止从upgrade_lockunique_lock 的转换。
  • unique_lock 转换为upgrade_lock

已全部放入namespace acme。把它放在你想要的任何命名空间中。

要求

编译器需要支持“rvalue-this”限定符和显式转换运算符。

免责声明

该代码仅经过轻微测试。如果您发现错误,我将不胜感激。

可以通过使用std::atomic 来优化upgrade_mutex。在这方面没有做任何努力(这是一项困难且容易出错的任务,比我目前花费的时间更多)。

【讨论】:

  • 感谢您的洞察力。我看到your proposal N3427,特别是“升级锁定概述”部分,它准确地解决了我的问题。你知道拒绝的理由吗?
  • 很遗憾我错过了那次会议。所以我不知道细节。它也在 2007 年的时间框架中针对 C++11 提出过,但当时被拒绝了,因为我们需要消除材料以便我们能够按时发布 C++09(这没有发生)。
  • @BillyONeal:如果这是基本原理,那是天真的错误。 upgrade_mutex 100% 独立于 shared_mutex。除了 upgrade_mutex 之外,VS 仍然可以有一个由 SRWLOCK 支持的 shared_mutex
  • @HowardHinnant 这是为 c++17 重新提出的吗?在我看来,这是 c++ 的线程支持库中的一个明显漏洞,而且似乎很容易插入。
  • @RichardHodges:不,不是。委员会中没有人表示有兴趣拥有它。现在为 C++17 提出新特性为时已晚,但总会有下一个标准 (C++2x)。如果您想提出建议,我可以帮助您了解如何做到这一点。如果您可以亲自提交提案,提案将获得最大的成功。
猜你喜欢
  • 1970-01-01
  • 2015-04-16
  • 1970-01-01
  • 1970-01-01
  • 2012-08-03
  • 1970-01-01
  • 2014-10-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多