2017-02-17 155 views
9

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

  • C11
  • gcc的TLS扩展
  • 并行线程
  • 的Windows API TLS
+2

你可以补充库,并提供一个C函数读取和写入这些thread_local变量? – kennytm

+0

是的。如果Rust没有必要的工具来做这件事,那么我打算编写一个小的粘合库来处理线程局部变量。但是,如果可能的话,我宁愿避免额外的构建依赖关系。 – Doe

+2

任何答案都需要你告诉我们你正在使用什么线程系统,以及你如何创建线程局部变量**。这样做的一个好方法是提供外部代码的[MCVE]和您创建的Rust代码,以显示您希望如何访问它。 – Shepmaster

回答

6

锈病每晚功能,它允许链接到外部线程局部变量。跟踪功能的稳定性here

C11/GCC TLS扩展

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

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

链接到两个外部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; 

上述锈代码的输出将是:

1 
1 
1 
1 
1 

当变量定义为线程本地时,应该这样做。

+0

优秀的答案。相应的跟踪问题似乎是https://github.com/rust-lang/rust/issues/29594。从这个问题看来,稳定似乎不太可能。 – Doe