我正在尝试了解在主线程的上下文中使用静态存储持续时间和线程本地存储持续时间来初始化和销毁命名空间范围和 block 范围对象的顺序规则。考虑这两个类:
struct Foo {
Foo() { std::cout << "Foo\n"; }
~Foo() { std::cout << "~Foo\n"; }
static Foo &instance();
};
struct Bar {
Bar() { std::cout << "Bar\n"; }
~Bar() { std::cout << "~Bar\n"; }
static Bar &instance();
};
除了它们的静态实例成员函数的实现之外,它们是相同的:
thread_local Foo t_foo;
Foo &Foo::instance() { return t_foo; }
Bar &Bar::instance() { static Bar s_bar; return s_bar; }
Bar 是一个 Meyers 单例,一个具有静态存储持续时间的 block 范围对象。
Foo 的实例是具有线程本地存储持续时间的 namespace 范围对象。
现在是 main 函数:
int main() {
Bar::instance();
Foo::instance();
}
这是 GCC 8.1.0 和 Clang 5.0.0 的输出:
Bar
Foo
~Foo
~Bar
在线试用:https://coliru.stacked-crooked.com/a/f83a9ec588aed921
我原以为 Foo 会首先被构建,因为它在命名空间范围内。我想允许实现将初始化推迟到对象的第一次 ODR 使用。我不知道它可以推迟到 block 作用域静态初始化之后,但我可以接受。
现在我颠倒了 main 中函数调用的顺序:
int main() {
Foo::instance();
Bar::instance();
}
这是输出:
Foo
Bar
~Foo
~Bar
现在我已经将 Foo 实例的第一次 odr-use 移动到第一次调用 Bar::instance 之前,并且初始化顺序与我一样预期。
但我认为对象应该按照与初始化相反的顺序销毁,但这似乎并没有发生。我错过了什么?
关于静态和线程本地存储持续时间的对象的初始化和销毁,cppreference 和标准说“程序启动时”,“线程启动时”,“程序结束时”,以及“当线程结束时”,但是这些概念在主线程的上下文中如何相互关联?或者更准确地说,第一个线程和最后一个线程?
在我的“真实”问题中,Foo(线程本地)被记录器使用,Bar 的基类的析构函数使用记录器,所以这是静态销毁命令的惨败。生成了其他线程,但在主线程中构造和销毁了 Bar(Meyers 单例)。如果我能理解排序规则,那么我就可以尝试解决“真正的”问题,而不必求助于随机尝试。
最佳答案
标准保证 Foo(线程本地存储)在 Bar(静态存储)之前被销毁:
The completions of the destructors for all initialized objects with thread storage duration within that thread strongly happen before the initiation of the destructors of any object with static storage duration.
但是,无法保证施工顺序。该标准只说线程本地应该在它的第一次 odr-use 之前构造:
A variable with thread storage duration shall be initialized before its first odr-use
关于c++ - 主线程中 block 作用域静态与命名空间作用域 thread_local 的初始化和销毁顺序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53999850/
在我的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”因此,为了解决
我的瘦服务器配置了nginx,我的ROR应用程序正在它们上运行。在我发布代码更新时运行thinrestart会给我的应用程序带来一些停机时间。我试图弄清楚如何优雅地重启正在运行的Thin实例,但找不到好的解决方案。有没有人能做到这一点? 最佳答案 #Restartjustthethinserverdescribedbythatconfigsudothin-C/etc/thin/mysite.ymlrestartNginx将继续运行并代理请求。如果您将Nginx设置为使用多个上游服务器,例如server{listen80;server
如果您尝试在Ruby中的nil对象上调用方法,则会出现NoMethodError异常并显示消息:"undefinedmethod‘...’fornil:NilClass"然而,有一个tryRails中的方法,如果它被发送到一个nil对象,它只返回nil:require'rubygems'require'active_support/all'nil.try(:nonexisting_method)#noNoMethodErrorexceptionanymore那么try如何在内部工作以防止该异常? 最佳答案 像Ruby中的所有其他对象
我遵循了教程http://gettingstartedwithchef.com/,第1章。我的运行list是"run_list":["recipe[apt]","recipe[phpap]"]我的phpapRecipe默认Recipeinclude_recipe"apache2"include_recipe"build-essential"include_recipe"openssl"include_recipe"mysql::client"include_recipe"mysql::server"include_recipe"php"include_recipe"php::modul
我在Rails工作并有以下类(class):classPlayer当我运行时bundleexecrailsconsole然后尝试:a=Player.new("me",5.0,"UCLA")我回来了:=>#我不知道为什么Player对象不会在这里初始化。关于可能导致此问题的操作/解释的任何建议?谢谢,马里奥格 最佳答案 havenoideawhythePlayerobjectwouldn'tbeinitializedhere它没有初始化很简单,因为你还没有初始化它!您已经覆盖了ActiveRecord::Base初始化方法,但您没有调
我有用于控制用户任务的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方法与在第二个示例中使用实例变量之间是
如何将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.你能做的最好的事情是:
我们目前正在为ROR3.2开发自定义cms引擎。在这个过程中,我们希望成为我们的rails应用程序中的一等公民的几个类类型起源,这意味着它们应该驻留在应用程序的app文件夹下,它是插件。目前我们有以下类型:数据源数据类型查看我在app文件夹下创建了多个目录来保存这些:应用/数据源应用/数据类型应用/View更多类型将随之而来,我有点担心应用程序文件夹被这么多目录污染。因此,我想将它们移动到一个子目录/模块中,该子目录/模块包含cms定义的所有类型。所有类都应位于MyCms命名空间内,目录布局应如下所示:应用程序/my_cms/data_source应用程序/my_cms/data_ty
我对如何计算通过{%assignvar=0%}赋值的变量加一完全感到困惑。这应该是最简单的任务。到目前为止,这是我尝试过的:{%assignamount=0%}{%forvariantinproduct.variants%}{%assignamount=amount+1%}{%endfor%}Amount:{{amount}}结果总是0。也许我忽略了一些明显的东西。也许有更好的方法。我想要存档的只是获取运行的迭代次数。 最佳答案 因为{{incrementamount}}将输出您的变量值并且不会影响{%assign%}定义的变量,我