2017-01-14 11 views
3

У меня есть эта Rust программа:Являются ли статические переменные неустойчивыми?

use std::{thread, time}; 

static mut c:bool = false; 

fn main() { 
    unsafe { 
     // call some FFI program which sets up signals 
     c = false; 
     while !c { 
      thread::sleep(time::Duration::from_millis(10)); 
     } 
    } 
} 

Я дам указатель на c в какой-то программе FFI, который устанавливает сигналы, которые изменяют c. Как я могу убедиться, что компилятор не устранит цикл while, так как он принимает c никогда не изменится?

C имеет ключевое слово volatile, которое сообщает компилятору не оптимизировать эти примеры. Как я могу сказать компилятору Rusty то же самое?

(Я пытался прочитать код LLVM IR, но не смог понять, как его понять).

+1

bummer, забыли ключевое слово 'mut', которое, конечно же, имеет решающее значение в этом контексте. Исправлено его, а также добавлен комментарий, где я бы назвал FFI – hansaplast

+1

[Этот reddit thread] (https://www.reddit.com/r/rust/comments/40ewem/what_is_the_rust_equivalent_for_cs_volatile/) может быть полезной. – ljedrz

ответ

1

Нет, статические переменные нестабильны.

Правильное решение в пределах ржавчины - использовать AtomicBool. Следующий пример (из std::sync::atomic) очень похоже на то, что вы хотите сделать:

use std::sync::Arc; 
use std::sync::atomic::{AtomicUsize, Ordering}; 
use std::thread; 

fn main() { 
    let spinlock = Arc::new(AtomicUsize::new(1)); 

    let spinlock_clone = spinlock.clone(); 
    let thread = thread::spawn(move|| { 
     spinlock_clone.store(0, Ordering::SeqCst); 
    }); 

    // Wait for the other thread to release the lock 
    while spinlock.load(Ordering::SeqCst) != 0 {} 

    if let Err(panic) = thread.join() { 
     println!("Thread had an error: {:?}", panic); 
    } 
} 

Вы могли бы сделать это таким образом, через некоторый обратный вызов из обработчика сигнала в Русте.

Существуют также небезопасные функции std::ptr::read_volatile и std::ptr::write_volatile, которые могут использоваться для прямого доступа к памяти. Обычно они должны использоваться только для доступа к аппаратным регистрам или для реализации безопасных абстракций.

+0

В первую очередь, 'std :: ptr :: read_volatile' НЕ настраивает барьеры памяти, поэтому НЕ работает для передачи сигналов с поперечным потоком, поскольку аппаратное обеспечение может не выполнять необходимую синхронизацию. –

+0

спасибо, я пробовал только с «AtomicBool», и это не сработает, я думаю, что «Arc» вокруг него имеет решающее значение? Также: как бы я указал указатель на фактический bool на C? – hansaplast