2017-02-17 17 views
9

Для каждого из следующих реализаций хранения локального потока, как может внешнюю резьбу локальной переменный быть доступен в программах ржавчины с использованием стандартных механизмов FFI, как подвергается компилятору или стандартной библиотекой?Как получить доступ к внешним глобальным переменным, зависящим от потока, в Rust?

  • C11 расширение TLS
  • ССЗ
  • Pthreads
  • для Windows TLS API
+2

Вы можете дополнить библиотеку и обеспечивает функцию C для чтения и записи этих thread_local переменных? – kennytm

+0

Да. Я намерен написать небольшую библиотеку клеев, чтобы иметь дело с локальными переменными потока, если у Rust отсутствуют необходимые возможности для этого. Тем не менее, я предпочитаю избегать дополнительных зависимостей сборки, если это вообще возможно. – Doe

+2

Любой ответ потребует от вас рассказать нам, какую систему потоков вы используете и как создаете локальные переменные потока **. Отличным способом сделать это будет предоставление [MCVE] кода extern и кода Rust, который вы создали, который показывает, как вы хотите получить к нему доступ. – Shepmaster

ответ

6

Ржавчина имеет ночной функцию, которая позволяет связывающую внешние резьбы локальных переменных. Отслеживается стабилизация функции here.

C11/GCC TLS расширение

C11 определяет _Thread_local ключевое слово, чтобы определить thread-storage duration для объекта. Существует также псевдоним макроса thread_local.

GCC также реализует расширение Thread Local, которое использует __thread как ключевое слово.

Связывание с как внешнего С11 _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 

Ожидается, что переменная определяется как потоковая локальная.

+0

Отличный ответ. Соответствующая проблема отслеживания, похоже, https://github.com/rust-lang/rust/issues/29594. Из этого вопроса кажется, что стабилизация не представляется вероятной. – Doe

 Смежные вопросы

  • Нет связанных вопросов^_^