【问题标题】:How are foreign thread-local global variables accessed in Rust?Rust 中如何访问外部线程局部全局变量?
【发布时间】:2017-02-17 04:45:30
【问题描述】:

对于以下每个线程局部存储实现,如何使用编译器或标准库公开的标准 ffi 机制在 Rust 程序中访问外部线程局部变量?

  • C11
  • gcc 的 tls 扩展
  • 线程
  • Windows TLS API

【问题讨论】:

  • 你能补充库并提供一个C函数来读写那些thread_local变量吗?
  • 是的。如果 Rust 缺乏必要的工具,我打算编写一个小型胶水库来处理线程局部变量。但是,如果可能的话,我更愿意避免额外的构建依赖项。
  • 任何答案都需要您告诉我们您正在使用什么线程系统以及如何创建线程局部变量。一个很好的方法是提供外部代码的 minimal reproducible example 和您创建的 Rust 代码,以显示您希望如何访问它。
  • 如果线程局部变量声明为pub,您应该可以从任何地方访问它。请参阅 LocalKeythread_local 或此 playground
  • @Doe 是的,我误会了。我使用 gcc 添加了一个 C11 _Thread_local 解决方案的答案。

标签: multithreading rust ffi


【解决方案1】:

Rust 有一个夜间功能,它允许链接到外部线程局部变量。跟踪该功能的稳定性here

C11 / GCC TLS 扩展

C11 定义了_Thread_local 关键字来为对象定义thread-storage duration。还有一个thread_local 宏别名。

GCC 还实现了一个Thread Local 扩展,它使用__thread 作为关键字。

可以使用 nightly 链接到外部 C11 _Thread_local 和 gcc __thread 变量(使用 rustc 1.17.0-nightly (0e7727795 2017-02-19) 和 gcc 5.4 测试)

#![feature(thread_local)]

extern crate libc;

use libc::c_int;

#[link(name="test", kind="static")]
extern {
    #[thread_local]
    static mut test_global: c_int;
}

fn main() {
    let mut threads = vec![];
    for _ in 0..5 {
        let thread = std::thread::spawn(|| {
            unsafe {
                test_global += 1;
                println!("{}", test_global);
                test_global += 1;
            }
        });
        threads.push(thread);
    }

    for thread in threads {
        thread.join().unwrap();
    }
}

这允许访问声明为以下任一变量的变量:

_Thread_local extern int test_global;
extern __local int test_global;

上述 Rust 代码的输出将是:

1
1
1
1
1

这是预期的,当变量被定义为线程本地时。

【讨论】:

猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-05-17
  • 2018-10-28
  • 1970-01-01
  • 1970-01-01
  • 2013-12-25
  • 1970-01-01
  • 2011-04-15
相关资源
最近更新 更多