静态变量是否易变?

时间:2017-01-14 21:20:45

标签: static rust volatile

我有这个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关键字,告诉编译器不要在这些示例中进行优化。我怎么能告诉Rust编译器呢?

(我尝试阅读LLVM IR代码,但无法弄清楚如何理解它。)

1 个答案:

答案 0 :(得分:2)

不,静态变量不易变。

Rust中的正确解决方案是使用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);
    }
}

你可以通过从信号处理程序到Rust的回调来实现这一点。

还有不安全的函数std::ptr::read_volatilestd::ptr::write_volatile,它们可用于直接访问内存。通常,这些只应用于访问硬件寄存器或实现安全抽象。