Rust 标准库中的线程局部变量是如何工作的?

Rüd*_*ehn 5 multithreading thread-local thread-local-storage rust

Rust 标准库中的线程局部变量是如何工作的?我查看了代码,但在间接中迷失了方向。线程本地存储、OS 依赖模式和快速模式似乎有不同的配置。哪一个是默认的,我该如何选择使用哪一个?特别是,在 crate 中使用线程本地存储对 crate 用户有什么影响?

使用线程本地存储非常简单,生成的程序集看起来非常高效,但如果不完全理解其含义,我无法在库中使用该功能。

我也问过:

Nik*_*yar 9

您看到的不同配置与 相关#[thread_local],该功能旨在替换thread_local!宏以使用户代码更简单,例如:

#![feature(thread_local)]

#[thread_local]
pub static mut VAR: u64 = 42;
Run Code Online (Sandbox Code Playgroud)

但是,在撰写本文时,此功能尚未完全实现(您可以在此处找到跟踪问题)。它在编译的代码虽然在内部使用,那就是你在实际的“快”看到神奇的实施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();
Run Code Online (Sandbox Code Playgroud)

注意#[thread_local]顶部的属性。然后将其转换为 LLVM IR,因此 TLS(线程本地存储)的实际实现由 LLVM 承载并实现ELF TLS 模型。这是默认配置。

我该如何选择使用哪一种?

您需要编译自己的rustc版本,并target_thread_local省略该功能。在这种情况下,osstd::thread::LocalKey将被使用,然后,根据在一个平台上,它可以使用并行线程(UNIX) ,或Windows API的,或别的东西。

WebAssembly 是一个特例:由于它不支持线程,TLS 将被转换为简单的静态变量。