新的 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_mutex戴夫 S 提到
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,但我怀疑它确实如此。
我会对基于 std::atomic/condition_variable 或 GCC 事务内存的合理解决方法感到满意。
编辑:霍华德的回答解决了我的问题。他的proposal N3427包含对实现互斥升级的机制的很好的描述。我仍然欢迎基于 std::atomic/condition_variable 或 GCC 事务内存的变通方法。
最佳答案
不,它不能。该功能以 upgrade_mutex 和 upgrade_lock 的名称向委员会提出,但委员会选择拒绝该部分提案。目前没有任何工作可以重新设置该功能。
编辑
为了响应 user3761401 的问题中的“从这里去哪里”编辑,我在这里创建了一个部分残缺的 upgrade_mutex/upgrade_lock 实现:
https://github.com/HowardHinnant/upgrade_mutex
请随意使用。它在公共(public)领域。它只是经过轻微测试,不具备N3427 中描述的全部功能。 .特别是缺少以下功能:
unique_lock 转换为 shared_timed_lock。shared_timed_lock 转换为 unique_lock。upgrade_lock 转换为 unique_lock。话虽如此,我已经在 upgrade_mutex 中包含了这个功能,并且可以在这个低级别以非常丑陋的方式访问它(这样的例子在 main.cpp 中)。
N3427 中提到的其他锁转换可用。
shared_timed_lock 到 upgrade_lock 的尝试和定时转换。upgrade_lock 转换为 shared_timed_lock。upgrade_lock 到 unique_lock 的转换。unique_lock 转换为 upgrade_lock。已全部放入 namespace acme。把它放在你想要的任何命名空间中。
要求
编译器需要支持“rvalue-this”限定符和显式转换运算符。
免责声明
该代码仅经过轻微测试。如果您发现错误,我将不胜感激。
可以通过使用std::atomic来优化upgrade_mutex。在这方面没有做任何努力(这是一项困难且容易出错的任务,比我目前花费的时间更多)。
关于c++ - std::shared_timed_mutex 上的共享锁可以升级为独占锁吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24334735/
这似乎应该有一个直截了当的答案,但在Google上花了很多时间,所以我找不到它。这可能是缺少正确关键字的情况。在我的RoR应用程序中,我有几个模型共享一种特定类型的字符串属性,该属性具有特殊验证和其他功能。我能想到的最接近的类似示例是表示URL的字符串。这会导致模型中出现大量重复(甚至单元测试中会出现更多重复),但我不确定如何让它更DRY。我能想到几个可能的方向...按照“validates_url_format_of”插件,但这只会让验证干给这个特殊的字符串它自己的模型,但这看起来很像重溶液为这个特殊的字符串创建一个ruby类,但是我如何得到ActiveRecord关联这个类模型
我的瘦服务器配置了nginx,我的ROR应用程序正在它们上运行。在我发布代码更新时运行thinrestart会给我的应用程序带来一些停机时间。我试图弄清楚如何优雅地重启正在运行的Thin实例,但找不到好的解决方案。有没有人能做到这一点? 最佳答案 #Restartjustthethinserverdescribedbythatconfigsudothin-C/etc/thin/mysite.ymlrestartNginx将继续运行并代理请求。如果您将Nginx设置为使用多个上游服务器,例如server{listen80;server
我想设置一个默认日期,例如实际日期,我该如何设置?还有如何在组合框中设置默认值顺便问一下,date_field_tag和date_field之间有什么区别? 最佳答案 试试这个:将默认日期作为第二个参数传递。youcorrectlysetthedefaultvalueofcomboboxasshowninyourquestion. 关于ruby-on-rails-date_field_tag,如何设置默认日期?[rails上的ruby],我们在StackOverflow上找到一个类似的问
我将我的Rails应用程序部署到OpenShift,它运行良好,但我无法在生产服务器上运行“Rails控制台”。它给了我这个错误。我该如何解决这个问题?我尝试更新rubygems,但它也给出了权限被拒绝的错误,我也无法做到。railsc错误:Warning:You'reusingRubygems1.8.24withSpring.UpgradetoatleastRubygems2.1.0andrun`gempristine--all`forbetterstartupperformance./opt/rh/ruby193/root/usr/share/rubygems/rubygems
我正在尝试从Postgresql表(table1)中获取数据,该表由另一个相关表(property)的字段(table2)过滤。在纯SQL中,我会这样编写查询:SELECT*FROMtable1JOINtable2USING(table2_id)WHEREtable2.propertyLIKE'query%'这工作正常:scope:my_scope,->(query){includes(:table2).where("table2.property":query)}但我真正需要的是使用LIKE运算符进行过滤,而不是严格相等。然而,这是行不通的:scope:my_scope,->(que
我正在使用RubyonRails3.2.2,我想从我的模型/类中“提取”一些方法。也就是说,在不止一个类/模型中,我有一些方法(注意:方法与用户授权相关,并被命名为“CRUD方式”),这些方法实际上是相同的;所以我认为DRY方法是将这些方法放在“共享”模块或类似的东西中。实现该目标的常见且正确的方法是什么?例如,我应该将“共享”代码放在哪里(在哪些目录和文件中)?如何在我的类/模型中包含提到的方法?你有什么建议?注意:我正在寻找“RubyonRails制作东西的方式”。 最佳答案 一种流行的方法是使用ActiveSupport关注点
如何将send与+=一起使用?a=20;a.send"+=",10undefinedmethod`+='for20:Fixnuma=20;a+=10=>30 最佳答案 恐怕你不能。+=不是方法,而是语法糖。参见http://www.ruby-doc.org/docs/ProgrammingRuby/html/tut_expressions.html它说Incommonwithmanyotherlanguages,Rubyhasasyntacticshortcut:a=a+2maybewrittenasa+=2.你能做的最好的事情是:
我对如何计算通过{%assignvar=0%}赋值的变量加一完全感到困惑。这应该是最简单的任务。到目前为止,这是我尝试过的:{%assignamount=0%}{%forvariantinproduct.variants%}{%assignamount=amount+1%}{%endfor%}Amount:{{amount}}结果总是0。也许我忽略了一些明显的东西。也许有更好的方法。我想要存档的只是获取运行的迭代次数。 最佳答案 因为{{incrementamount}}将输出您的变量值并且不会影响{%assign%}定义的变量,我
我有一个.pfx格式的证书,我需要使用ruby提取公共(public)、私有(private)和CA证书。使用shell我可以这样做:#ExtractPublicKey(askforpassword)opensslpkcs12-infile.pfx-outfile_public.pem-clcerts-nokeys#ExtractCertificateAuthorityKey(askforpassword)opensslpkcs12-infile.pfx-outfile_ca.pem-cacerts-nokeys#ExtractPrivateKey(askforpassword)o
无论时间在哪个时区表示,时区差异是否总是被忽略?直觉上,对于那些使用UTC+2的人来说,从EPOCH开始经过的秒数应该更高。然而,事实并非如此。 最佳答案 Epoch基于utc时区https://en.wikipedia.org/wiki/Unix_time它与您当前所在的时区无关。 关于ruby-Time.to_i是否总是以UTC返回自EPOCH以来的秒数?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.