2017-02-17 94 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