gpt4 book ai didi

c++ - 我的编译器是否忽略了我未使用的静态 thread_local 类成员?

转载 作者:行者123 更新时间:2023-12-02 02:52:43 26 4
gpt4 key购买 nike

我想在我的类中进行一些线程注册,因此我决定添加对 thread_local 功能的检查:

#include <iostream>
#include <thread>

class Foo {
public:
Foo() {
std::cout << "Foo()" << std::endl;
}
~Foo() {
std::cout << "~Foo()" << std::endl;
}
};

class Bar {
public:
Bar() {
std::cout << "Bar()" << std::endl;
//foo;
}
~Bar() {
std::cout << "~Bar()" << std::endl;
}
private:
static thread_local Foo foo;
};

thread_local Foo Bar::foo;

void worker() {
{
std::cout << "enter block" << std::endl;
Bar bar1;
Bar bar2;
std::cout << "exit block" << std::endl;
}
}

int main() {
std::thread t1(worker);
std::thread t2(worker);
t1.join();
t2.join();
std::cout << "thread died" << std::endl;
}

代码很简单。我的 Bar 类有一个静态 thread_local 成员 foo 。如果创建了一个静态thread_local Foo foo,则意味着创建了一个线程。

但是当我运行代码时,Foo() 中不会打印任何内容,并且如果我删除 Bar 的构造函数中使用 foo 的注释,代码工作正常。

我在 GCC (7.4.0) 和 Clang (6.0.0) 上尝试过,结果是相同的。我猜编译器发现 foo 未使用并且不生成实例。所以

  1. 编译器是否忽略了static thread_local 成员?我怎么能够为此进行调试?
  2. 如果是这样,为什么普通的static成员不会出现这个问题?

最佳答案

你的观察没有问题。 [basic.stc.static]/2禁止消除具有静态存储持续时间的变量:

If a variable with static storage duration has initialization or a destructor with side effects, it shall not be eliminated even if it appears to be unused, except that a class object or its copy/move may be eliminated as specified in [class.copy].

其他存储持续时间不存在此限制。事实上,[basic.stc.thread]/2说:

A variable with thread storage duration shall be initialized before its first odr-use and, if constructed, shall be destroyed on thread exit.

这表明除非使用了 odr,否则不需要构造具有线程存储持续时间的变量。

<小时/>

但是为什么会出现这种差异呢?

对于静态存储持续时间,每个程序只有一个变量实例。其构造的副作用可能很大(有点像程序范围的构造函数),因此需要副作用。

然而,对于线程本地存储持续时间,存在一个问题:一个算法可能会启动很多线程。对于大多数线程来说,该变量是完全不相关的。如果外部物理模拟库调用std::reduce(std::execution::par_unseq, first, last),那就太搞笑了最终创建了很多foo实例,对吧?

当然,对于非 odr 使用的线程本地存储持续时间的变量的构造的副作用(例如,线程跟踪器)可以有合法的用途。然而,保证这一点的优势不足以弥补上述缺陷,因此只要不使用这些变量,就允许消除它们。 (不过,您的编译器可以选择不这样做。您也可以在 std::thread 周围创建自己的包装器来处理这个问题。)

关于c++ - 我的编译器是否忽略了我未使用的静态 thread_local 类成员?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58690627/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com