【问题标题】:Is eager thread_local initialization possible in C++?在 C++ 中是否可以进行急切的 thread_local 初始化?
【发布时间】:2019-03-16 13:27:41
【问题描述】:

[basic.stc.thread] 声明“具有线程存储持续时间的变量应在在其第一次使用 odr 之前 (6.2) 进行初始化,并且如果已构建,则应在线程退出时销毁。 "

这是否排除了在创建线程时急切地初始化命名空间范围thread_local 变量的实现,并且是否有任何主要编译器支持任何机制来通过某些注释强制执行此操作?

我有非常少量的性能关键 __thread 变量我想免于 thread_local 通常会发生的每次访问惰性初始化检查,但我目前需要通过单独的调用进行设置/拆卸为了保持__thread 对非平凡析构函数的限制等。我可以得到thread_local 保证每个线程的急切构造/销毁并且没有惰性初始化测试吗?

如果做不到这一点,处理__thread setup/teardown call registration 的已知最简洁的模式是什么?

【问题讨论】:

  • 我有点困惑。您是在处理一小组关键变量,还是需要无限扩展的注册过程?两者都没有意义。
  • 好问题。当我有这样的问题时,我会在 Godbolt 中编写一个简单的实现并分析程序集。
  • @groovyspaceman,在为此写答案时,我只是这样做了,在这种情况下它不是很有帮助:gcc.godbolt.org/z/EaZ9cp 问题是很多代码生成将发生在链接器中。
  • @Frank,我想要一个可扩展的系统,我只是想阻止关于“懒惰的 init 存在是有原因的”的话题。我不是这个产品/平台的唯一开发者,注册机制越不集中,其他开发者肯定会更开心。
  • @Jeff 问题是,特别是在一个大型项目中,强制在每个线程中实例化许多线程本地变量的想法,无论使用情况如何,这让我有点不舒服。对于一小部分特定变量作为工程折衷方案是有意义的,但作为折衷方案,我不想让它变得容易添加。

标签: c++ initialization lazy-initialization thread-local static-initialization


【解决方案1】:

我能否获得thread_local,保证每个线程都急切地构造/销毁并且没有惰性初始化测试?

不太可能。

如果做不到这一点,处理__thread setup/teardown 呼叫注册的已知最简洁的模式是什么?

您可以将所有线程特定信息打包到一个对象中,该对象通过一个线程特定指针访问,该指针在线程启动时被初始化。例如:

struct ThreadContext {
    thread_local static ThreadContext* instance;

    ThreadContext() {
        assert(!instance);
        instance = this;
    }

    ~ThreadContext() {
        instance = 0;
    }

    ThreadContext(ThreadContext const&) = delete;
    ThreadContext& operator=(ThreadContext const&) = delete;
};

thread_local ThreadContext* ThreadContext::instance = 0;

void thread_function() {
    ThreadContext context;

    // Access it elsewhere as:
    ThreadContext::instance;  
}

ThreadContext* getThisThreadContext() {
    return ThreadContext::instance;  
    // No init check here. Just one move:
    // mov rax, QWORD PTR fs:ThreadContext::instance@tpoff
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-09-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-02-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多