可以将std :: shared_timed_mutex上的共享锁升级为独占锁吗? [英] Can a shared lock on a std::shared_timed_mutex be upgraded to an exclusive lock?

查看:246
本文介绍了可以将std :: shared_timed_mutex上的共享锁升级为独占锁吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

The new std::shared_timed_mutex allows for two types of locks: shared and exclusive.

如果拥有共享锁,是否有任何方法可以自动将其原子交换(升级")为独占锁?换句话说,给出以下代码,如何避免非原子掉落并重新锁定?

If one holds a shared lock, is there any way to atomically exchange it ("upgrade it") to an exclusive lock? In other words, given the following code, how can I avoid the non-atomic drop and re-lock?

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()之类的东西)代替.

Ideally, m.unlock_shared(); m.lock(); could be replaced with something like m.upgrade_to_exclusive(); (or something like the boost::.upgrade_to_unique_lock()).

在类似的问题中,但对于Boost的shared_mutex 戴夫S提到

In a similar question but for Boost's shared_mutex Dave S mentions

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

It is impossible to convert from a shared lock to a unique lock, or a shared lock to an upgradeable lock without releasing the shared lock first.

我不确定这是否适用于std :: shared_mutex,尽管我怀疑是这样.

I'm not certain whether this applies to std::shared_mutex, though I suspect it does.

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

I would be happy with a reasonable work-around based on std::atomic/condition_variable or GCC's transactional memory.

编辑:霍华德的答案解决了我的问题.他的提案N3427 包含对实现互斥体升级的机制.我仍然欢迎基于std :: atomic/condition_variable或GCC的事务性内存的变通方法.

Howard's answer addresses my question. His proposal N3427 contains nice descriptions of a mechanism to achieve mutex upgrading. I still welcome work-arounds based on std::atomic/condition_variable or GCC's transactional memory.

推荐答案

否,不能.该功能已以upgrade_mutexupgrade_lock的名称提交给委员会,但委员会选择拒绝该部分提案.当前没有任何工作可以重新设定该功能.

No, it can not. That functionality was proposed to the committee under the name upgrade_mutex and upgrade_lock, but the committee chose to reject that portion of the proposal. There is currently no work under way to re-prepose that functionality.

修改

为响应user3761401问题中的从这里去哪里"编辑,我在这里创建了upgrade_mutex/upgrade_lock的部分残缺实现:

In response to the "where to go from here" edit in user3761401's question, I've created a partially crippled implementation of upgrade_mutex/upgrade_lock here:

https://github.com/HowardHinnant/upgrade_mutex

随时使用.它是在公共领域.它只是经过严格测试,并且不具有中描述的全部功能. N3427 .具体来说,缺少以下功能:

Feel free to use this. It is in the public domain. It is only lightly tested, and it does not have the full functionality described in N3427. Specifically the following functionality is missing:

  • 不能将unique_lock转换为shared_timed_lock.
  • 无法将shared_timed_lock尝试或定时转换为unique_lock.
  • 无法将upgrade_lock尝试或定时转换为unique_lock.
  • One can not convert a unique_lock to a shared_timed_lock.
  • One can not try- or timed-convert a shared_timed_lock to a unique_lock.
  • One can not try- or timed-convert a upgrade_lock to a unique_lock.

话虽如此,我已经在upgrade_mutex中包含了此功能,并且可以以非常难看的方式在较低的级别对其进行访问(此类示例在main.cpp中).

That being said, I've included this functionality in upgrade_mutex and it can be accessed at this low level in a very ugly manner (such examples are in main.cpp).

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

The other lock conversions mentioned in N3427 are available.

  • shared_timed_lockupgrade_lock的尝试和定时转换.
  • upgrade_lockshared_timed_lock的转换.
  • 阻止从upgrade_lockunique_lock的转换.
  • unique_lock转换为upgrade_lock.
  • try- and timed-conversions from shared_timed_lock to upgrade_lock.
  • conversion from upgrade_lock to shared_timed_lock.
  • blocking conversion from upgrade_lock to unique_lock.
  • conversion from unique_lock to upgrade_lock.

所有内容都已放在namespace acme中.将其放在您想要的任何命名空间中.

It has all been put in namespace acme. Put it in whatever namespace you want.

要求

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

The compiler needs to support "rvalue-this" qualifiers, and explicit conversion operators.

免责声明

该代码仅经过了轻微测试.如果您发现错误,请提出请求.

The code has been only lightly tested. If you find bugs I would appreciate a pull request.

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

It is possible to optimize the upgrade_mutex through the use of std::atomic. No effort has been done on that front (it is a difficult and error prone task, taking more time than I have at the moment).

这篇关于可以将std :: shared_timed_mutex上的共享锁升级为独占锁吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆