可以将std :: shared_timed_mutex上的共享锁升级为独占锁吗?

use*_*401 16 c++ multithreading c++11 c++14

新的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();
Run Code Online (Sandbox Code Playgroud)

理想情况下,m.unlock_shared(); m.lock();可以用类似m.upgrade_to_exclusive();(或类似的东西boost::.upgrade_to_unique_lock())替换.

在一个类似的问题,但对于Boost的shared_mutex Dave S提及

在不释放共享锁的情况下,无法从共享锁转换为唯一锁,或共享锁转换为可升级锁.

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

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

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

How*_*ant 17

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

编辑

在user3761401的问题中,为了回应"从这里开始"的编辑,我在upgrade_mutex/upgrade_lock这里创建了一个部分残缺的实现:

https://github.com/HowardHinnant/upgrade_mutex

随意使用它.它属于公共领域.它只是经过轻微测试,并没有N3427中描述的全部功能.具体而言,缺少以下功能:

  • 一个人无法将a转换unique_lock为a shared_timed_lock.
  • 人们无法尝试或定时将a转换shared_timed_lock为a unique_lock.
  • 人们无法尝试或定时将a转换upgrade_lock为a unique_lock.

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

可以使用N3427中提到的其他锁定转换.

  • 尝试和定时转换shared_timed_lockupgrade_lock.
  • 转换upgrade_lockshared_timed_lock.
  • 阻止转换upgrade_lockunique_lock.
  • 转换unique_lockupgrade_lock.

它已全部投入使用namespace acme.把它放在你想要的任何名称空间中.

要求

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

免责声明

代码只是经过了轻微的测试.如果你发现错误,我会很感激拉取请求.

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

  • @BillyONeal:如果这是理由,那就天真地弄错了.`upgrade_mutex`是100%独立于`shared_mutex`.除了`upgrade_mutex`之外,VS仍然可以拥有``SRWLOCK`支持的`shared_mutex`. (2认同)
  • @RichardHodges:不,不是。委员会中没有人表示对此有兴趣。现在为C ++ 17提出新功能为时已晚,但是始终存在下一个标准(C ++ 2x)。如果您想提出建议,我可以在后勤方面为您提供帮助。如果可以亲自提出建议,则建议最成功。 (2认同)