How to Define Thread-Local Local Static Variables

How to define thread-local local static variables?

on Windows using Windows API: TlsAlloc()/TlsSetValue()/TlsGetValue()

on Windows using compiler intrinsic: use _declspec(thread)

on Linux (other POSIX???) : get_thread_area() and related

Are static variables automatically thread local?

There was static for block-scope variables before the C language specification acknowledged threads or had any support for them, much less _Thread_local specifically. In that context, when not combined with _Thread_local, it specifies static storage duration, meaning that the variable comes into existence (as if) at the beginning of program execution and exists and maintains its last-stored value for the entire run of the program. An object with static storage duration is shared by all threads.

On the other hand, _Thread_local always specifies thread storage duration, which means that the object so declared exists and maintains its last-stored value for the entire lifetime of a thread, and that the declared identifier designates a different object in each thread. When an object is declared _Thread_local at block scope, it must also bear either the extern or static qualifier, which conveys its linkage -- external or none.

extern declarations of any kind at block scope are unusual, but they do occasionally serve a useful purpose. Most of the time, though, static _Thread_local is what you will want for thread-local, block-scope variables.

thread_local static variables in a dynamic loaded library – when are they created?

What cppreference says is paraphrased. What's actually in the standard is

All variables declared with the thread_local keyword have thread storage duration. The storage for these
entities lasts 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.

There's nothing in there about when, exactly, the storage is allocated, just that it lasts for the duration of the thread. This means it could be allocated when the thread is created, or when the variable is first used, or possibly a combination of both.

The variable may not be constructed (I assume this is what you mean when you say "create an instance") when the storage is allocated. That depends on where and how the variable is defined. But, if it is constructed, it won't be destroyed until the thread ends.

Support for dynamically loading libraries via dlopen or LoadLibrary is a compiler/platform extension, and not part of the language. How that interacts with thread_local would also be platform specific.

Are C++11 thread_local variables automatically static?

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.

Local static variables for each thread

You can use the thread_local keyword which indicates that the object has a thread storage duration. You can use it like that :

static thread_local int V;

If you want more information about storage class specifiers, you can check CppReference.

Static Variables and Thread-Local Storage

It appears that this problem was caused by a bug in tz.cpp which has since been fixed.

The bug was that there was a namespace scope variable whose initialization was not guaranteed in the proper order. This was fixed by turning that variable into a function-local-static to ensure the proper initialization order.

My apologies to all who might have been impacted by this bug. And my thanks to all those who have reported it.

C++11 : Using local static variables in multithreaded program caused coredump

But in practice, program is coredump in assert randomly. Can U tell me why ?

Because you have a data race -- multiple threads are trying to read and write the same variable without any synchronization.

The index is a global variable. You need to guard access to it with a mutex.

Udate:

But localMap is not a global variable, data race cannot explain one index repeated twice.

  1. A program with a data race (undefined behavior) can produce any result.
  2. Yes, it can.

Consider the following instruction interleaving (time goes downwards):

  • T1 loads index into register (say 5).
  • T2 loads index (5 again)
  • T1 increments index to 6, stores "6" into its map
  • T1 loads 6, increments index to 7, stores "7" into its map
  • T2 "increments" index to 6, stores "6" into its own map
  • T1 loads 6, increments it to 7, tries to store "7" into its map ==> assertion failure!

The issue is that index++ is not an atomic operation, and (without mutex) other threads may interfere with it.

thread_local vs local variable in C++

thread_local implies static when static is omitted.

A local static variable preserves its value when a given function is called multiple times. You may read about static variable elsewhere.

Now, I assume you do know what static variable is - the important things are just:

  • static variables have local scope
  • (but) static variables have global existence

The second point makes a static variable's memory accessible to other functions by C++ references and pointers - it proves that the static variable has just one copy - across all threads of the process. You need to know what threads are and how to create/program threads.

Now, to the question. You know that Global variables have global scope and global accessibility, but when you run two or more instances of your program, both/all of them would have a SEPARATE copy of that global variable. That means each process would have a separate copy of that global variable.

So, what if you wanted to have a SEPARATE copy of static variable per thread? You use thread_static. Each thread will have a separate copy of that static variable.

Interestingly, you can apply thread_local to global variables also - thence each thread will receive a separate copy of those global variables also!

// Globals
int counter;
thread_local int this_thread_counter; // Each thread will have separate copy

Now, think how strtok would work - think about the (concurrent) calls to strtok !

Why ThreadLocal variable need to static?

Answer to this question lies into ThreadLocal implementation .

Think ThreadLocal as a container

ThreadLocal is a container that maintain a ThreadLocalMap internally , This ThreadLocalMap is the key why threadlocal need to be static(although not necessary ,but suggestion is keep it static).

Because we want single container per class , not container per instance .If we have container per instance we will be having as many container as instance and that will created memory leak .

More detail here

  1. http://www.0xcafefeed.com/2004/06/of-non-static-threadlocals-and-memory/
  2. https://www.appneta.com/blog/introduction-to-javas-threadlocal-storage/

Java ThreadLocal static?

As per the definition of ThreadLocal class

This class provides thread-local variables. These variables differ
from their normal counterparts in that each thread that accesses one
(via its get or set method) has its own, independently initialized
copy of the variable.
ThreadLocal instances are typically private
static fields in classes that wish to associate state with a thread
(e.g., a user ID or Transaction ID).

That means say 2 threads t1 & t2 executes someBMethod() and they end up setting x1 & x2(Instances of X) respectively. Now when t1 comes and executes someCMethod() it gets x1 (which is set by itself earlier) and t2 gets x2.

In other words, its safe to have a single static instance of ThreadLocal, because internally it does something like this when you invoke set

set(currentThread, value) //setting value against that particular thread

and when you invoke get

get(currentThread) //getting value for the thread


Related Topics



Leave a reply



Submit