C + + 11线程局部变量是自动静态的吗?

这两段代码是否有区别:

void f() {
thread_local vector<int> V;
V.clear();
... // use V as a temporary variable
}

还有

void f() {
static thread_local vector<int> V;
V.clear();
... // use V as a temporary variable
}

背景故事: 最初我有一个 STATIC 向量 V (用于保存一些中间值,每次输入函数时它都会被清除)和一个单线程程序。我想把程序变成一个多线程的程序,所以我必须设法去掉这个静态修饰符。我的想法是将每个静态转换为 thread _ local,而不用担心其他任何事情?这种做法会适得其反吗?

54815 次浏览

Yes, "thread-local storage" is very similar to "global" (or "static storage"), only that instead of "duration of the entire program" you have "duration of the entire thread". So a block-local thread-local variable is initialized the first time control passes through its declaration, but separately within each thread, and it's destroyed when the thread ends.

According to the C++ Standard

When thread_local is applied to a variable of block scope the storage-class-specifier static is implied if it does not appear explicitly

So it means that this definition

void f() {
thread_local vector<int> V;
V.clear();
... // use V as a temporary variable
}

is equivalent to

void f() {
static thread_local vector<int> V;
V.clear();
... // use V as a temporary variable
}

However, a static variable is not the same as a thread_local variable.

1 All variables declared with the thread_local keyword have thread storage duration. The storage for these entities shall last for the duration of the thread in which they are created. There is a distinct object or reference per thread, and use of the declared name refers to the entity associated with the current thread

To distinguish these variables the standard introduces a new term thread storage duration along with static storage duration.

Thread local storage is static but it behaves quite differently from simple static storage.

When you declare a variable static there is exactly one instance of the variable. The compiler/runtime system guarantees that it will be initialized for you sometime before you actually use it, without specifying exactly when (some details omitted here.)

C++11 guarantees that this initialization will be thread safe, however before C++11 this thread safety was not guaranteed. For example

static X * pointer = new X;

could leak instances of X if more than one thread hit the static initialization code at the same time.

When you declare a variable thread local there are potentially many instances of the variable. You could think of them as being in a map that was indexed by thread-id. That means each thread sees its own copy of the variable.

Once again, if the variable is initialized the compiler/runtime system guarantees that this initialization will happen before the data is used and that the initialization will happen for each thread that uses the variable. The compiler also guarantees that initiation will be thread safe.

The thread safety guarantees means that there can be quite a bit of behind-the-scenes code to make the variable behave the way you expect it to -- especially considering that the compiler has no way of knowing ahead of time exactly how many threads will exist in your program and how many of these will touch the thread local variable.

When used with thread_local, static is implied in block-scope (see @Vlad's answer), requied for a class member; I guess, means linkage for namespace scope.

Per 9.2/6:

Within a class definition, a member shall not be declared with the thread_local storage-class-specifier unless also declared static

To answer the original question:

Are C++11 thread_local variables automatically static?

There is no choice, except for namespace-scope variables.

Is there a difference between these two code segments:

No.