How do the thread local variables in the Rust standard library work? How do the thread local variables in the Rust standard library work? multithreading multithreading

How do the thread local variables in the Rust standard library work?


The different configurations you see are related to #[thread_local], a feature that is intended to replace the thread_local! macro to make the user code more straightforward, e.g.:

#![feature(thread_local)]#[thread_local]pub static mut VAR: u64 = 42;

However, at the moment of writing, this feature is not fully implemented yet (you can find the tracking issue here). It is used internally in the compiler code though, and that is the magic you see in the actual 'fast' implementation in std::thread::LocalKey:

#[thread_local]#[cfg(all(    target_thread_local,    not(all(target_arch = "wasm32", not(target_feature = "atomics"))),))]static __KEY: $crate::thread::__FastLocalKeyInner<$t> =    $crate::thread::__FastLocalKeyInner::new();

Notice the #[thread_local] attribute at the top. It is then translated down to LLVM IR, so the actual implementation of TLS (thread-local storage) is carried by LLVM and implements the ELF TLS models. This is the default configuration.

how do I choose which one to use?

You'll need to compile your own rustc version with the target_thread_local feature omitted. In that case, the os variant of std::thread::LocalKey will be used, and then, depending on a platform, it can use pthreads (Unix), or Windows API, or something else.

WebAssembly is a special case: as it doesn't support threads, TLS will be translated down to simple static variables.