假设我有这样的代码:
#include "boost/thread/mutex.hpp"
using boost::mutex;
typedef mutex::scoped_lock lock;
mutex mut1, mut2;
void Func() {
// ...
}
void test_raiicomma_1() {
lock mut1_lock(mut1);
Func();
}
void test_raiicomma_2() {
(lock(mut1)), Func();
}
void test_raiicomma_3() {
(lock(mut1)), (lock(mut2)), Func(); // Warning!
}
int main()
{
test_raiicomma_1();
test_raiicomma_2();
test_raiicomma_3();
return 0;
}
如果函数 test_raiicomma_1() 被多个线程调用,它会锁定一个互斥量以防止任何其他线程同时调用 Func()。互斥锁在构造变量 mut1_lock 时被锁定,并在超出范围并被析构时释放。
这工作得很好,但就风格而言,需要为持有锁的临时对象命名让我很烦。函数 test_raiicomma_2() 试图通过初始化锁对象并在一个表达式中调用函数 Func() 来避免这种情况。
在 Func() 返回后,直到表达式结束才会调用临时对象析构函数是否正确? (如果是这样,您认为使用这个习惯用法是否值得,或者在单独的语句中声明锁是否总是更清楚?)
如果函数 test_raiicomma_3() 需要锁定两个互斥量,互斥量在调用 Func() 之前按顺序锁定,然后释放,是否正确,但不幸的是,可能会以任一顺序发布?
最佳答案
Is it correct that the temporary object destructor will not be called until the end of the expression, after Func() has returned?
保证构造函数和析构函数都被调用,因为它们有副作用,并且破坏只会发生在完整表达式的末尾。
我相信它应该有效
If the function test_raiicomma_3() needs to lock two mutexes, is it correct that the mutexes will be locked in order before calling Func(), and released afterwards, but may unfortunately be released in either order?
逗号总是从左到右求值,范围内的自动变量总是以创建的相反顺序销毁,所以我认为甚至可以保证它们也以(正确的)顺序释放
正如 litb 在评论中指出的那样,您需要大括号,否则您的表达式将被解析为声明。
(If so, do you think it's ever worthwhile to use this idiom, or is it always clearer to declare the lock in a separate statement?)
我不这么认为,为了获得非常非常少的 yield 而混淆...... 我总是使用非常明确的锁和非常明确的范围(通常在一个 block 中使用额外的 {}),体面的线程安全代码在没有“特殊”代码的情况下已经足够困难,并且在我看来保证代码非常清晰。
当然是 YMMW :)
关于c++ - 在逗号运算符的 LHS 中初始化匿名互斥锁持有类实例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1393454/
假设我做了一个模块如下:m=Module.newdoclassCendend三个问题:除了对m的引用之外,还有什么方法可以访问C和m中的其他内容?我可以在创建匿名模块后为其命名吗(就像我输入“module...”一样)?如何在使用完匿名模块后将其删除,使其定义的常量不再存在? 最佳答案 三个答案:是的,使用ObjectSpace.此代码使c引用你的类(class)C不引用m:c=nilObjectSpace.each_object{|obj|c=objif(Class===objandobj.name=~/::C$/)}当然这取决于
在我的gem中,我需要yaml并且在我的本地计算机上运行良好。但是在将我的gem推送到rubygems.org之后,当我尝试使用我的gem时,我收到一条错误消息=>"uninitializedconstantPsych::Syck(NameError)"谁能帮我解决这个问题?附言RubyVersion=>ruby1.9.2,GemVersion=>1.6.2,Bundlerversion=>1.0.15 最佳答案 经过几个小时的研究,我发现=>“YAML使用未维护的Syck库,而Psych使用现代的LibYAML”因此,为了解决
我正在使用ruby1.9解析以下带有MacRoman字符的csv文件#encoding:ISO-8859-1#csv_parse.csvName,main-dialogue"Marceu","Giveittohimóhe,hiswife."我做了以下解析。require'csv'input_string=File.read("../csv_parse.rb").force_encoding("ISO-8859-1").encode("UTF-8")#=>"Name,main-dialogue\r\n\"Marceu\",\"Giveittohim\x97he,hiswife.\"\
我的瘦服务器配置了nginx,我的ROR应用程序正在它们上运行。在我发布代码更新时运行thinrestart会给我的应用程序带来一些停机时间。我试图弄清楚如何优雅地重启正在运行的Thin实例,但找不到好的解决方案。有没有人能做到这一点? 最佳答案 #Restartjustthethinserverdescribedbythatconfigsudothin-C/etc/thin/mysite.ymlrestartNginx将继续运行并代理请求。如果您将Nginx设置为使用多个上游服务器,例如server{listen80;server
我在Rails工作并有以下类(class):classPlayer当我运行时bundleexecrailsconsole然后尝试:a=Player.new("me",5.0,"UCLA")我回来了:=>#我不知道为什么Player对象不会在这里初始化。关于可能导致此问题的操作/解释的任何建议?谢谢,马里奥格 最佳答案 havenoideawhythePlayerobjectwouldn'tbeinitializedhere它没有初始化很简单,因为你还没有初始化它!您已经覆盖了ActiveRecord::Base初始化方法,但您没有调
请帮助我理解范围运算符...和..之间的区别,作为Ruby中使用的“触发器”。这是PragmaticProgrammersguidetoRuby中的一个示例:a=(11..20).collect{|i|(i%4==0)..(i%3==0)?i:nil}返回:[nil,12,nil,nil,nil,16,17,18,nil,20]还有:a=(11..20).collect{|i|(i%4==0)...(i%3==0)?i:nil}返回:[nil,12,13,14,15,16,17,18,nil,20] 最佳答案 触发器(又名f/f)是
我有用于控制用户任务的Rails5API项目,我有以下错误,但并非总是针对相同的Controller和路由。ActionController::RoutingError:uninitializedconstantApi::V1::ApiController我向您描述了一些我的项目,以更详细地解释错误。应用结构路线scopemodule:'api'donamespace:v1do#=>Loginroutesscopemodule:'login'domatch'login',to:'sessions#login',as:'login',via::postend#=>Teamroutessc
我正在阅读一本关于Ruby的书,作者在编写类初始化定义时使用的形式与他在本书前几节中使用的形式略有不同。它看起来像这样:classTicketattr_accessor:venue,:datedefinitialize(venue,date)self.venue=venueself.date=dateendend在本书的前几节中,它的定义如下:classTicketattr_accessor:venue,:datedefinitialize(venue,date)@venue=venue@date=dateendend在第一个示例中使用setter方法与在第二个示例中使用实例变量之间是
我没有理解以下行为(另请参阅inthisSOthread):defdef_testputs'def_test.in'yieldifblock_given?puts'def_test.out'enddef_testdoputs'def_testok'endblock_test=procdo|&block|puts'block_test.in'block.callifblockputs'block_test.out'endblock_test.calldoputs'block_test'endproc_test=procdoputs'proc_test.in'yieldifblock_gi
如何将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.你能做的最好的事情是: