2017-02-17 17 views
9

以下の各スレッドローカルストレージ実装について、コンパイラまたは標準ライブラリによって公開される標準のffiメカニズムを使用して、Rustプログラムで外部スレッドローカル変数にアクセスするにはどうすればよいですか?Rustで外部スレッドローカルグローバル変数はどのようにアクセスされますか?

  • C11
  • は、GCCのTLS拡張
  • pthreadsの
  • のWindows TLS API
+2

ライブラリを補完し、それらのthread_local変数を読み書きするためのC関数を提供できますか? – kennytm

+0

はい。 Rustに必要な機能が不足している場合は、スレッドローカル変数を処理するための小さなグルーライブラリを作成することを私の意図しています。しかし、可能な限り、余分なビルドの依存関係を避ける方がよいです。 – Doe

+2

答えがあれば、あなたが使っているスレッドシステムとスレッドローカル変数の作成方法を教えてください。それを実行する素晴らしい方法は、externコードの[MCVE]と、あなたがそれにアクセスする方法を示す作成したRustコードを提供することです。 – Shepmaster

答えて

6

錆が外部のスレッドローカル変数にリンクできます毎晩機能を持っています。機能の安定化は、hereと追跡されます。

C11/GCC TLS拡張

C11は、オブジェクトのthread-storage durationを定義する_Thread_localキーワードを定義します。 thread_localマクロエイリアスも存在します。

GCCは__threadをキーワードに使用してThread Localという拡張も実装しています。

外部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

関連する問題