将本地值推送到静态mut的安全方法

时间:2016-05-05 21:10:12

标签: rust

是否有安全的方法将本地值kv推送到static mut TABLE

static mut TABLE: [KV; 100] = [KV { k: -1, v: -1 }; 100];

#[derive(Debug, Clone, Copy)]
struct KV {
    k: i32,
    v: i32,
}

fn fun(i: usize) {
    let kv = KV { k: 0, v: 0 };
    unsafe {
        TABLE[i] = kv;
    }
}

1 个答案:

答案 0 :(得分:3)

不改变TABLE的类型,答案是否定的。

解释the section on static in the Rust book

  

因为TABLE是可变的,一个线程可以更新它而另一个线程正在读取它,导致内存不安全。访问和变更static mut都是不安全的,因此必须在unsafe块中进行

如果你知道你只有一个线程,你可以决定使用不安全的块,但如果没有,你需要更改表的类型以安全地从多个线程访问它。

要安全地执行此操作,您需要互斥。标准库提供std::sync::Mutex。要创建Mutex的静态引用,您需要the crate lazy_static。使用这两种成分,您可以像这样使用您的表:

#[macro_use]
extern crate lazy_static;

use std::sync::Mutex;

lazy_static! {
    static ref TABLE: Mutex<[KV; 100]> = Mutex::new([KV { k: -1, v: -1 }; 100]);
}

#[derive(Debug, Clone, Copy)]
struct KV {
    k: i32,
    v: i32,
}

fn update_table(i: usize, elem: KV) {
    let mut table = TABLE.lock().unwrap();
    table[i] = elem;
}

fn read_table(i: usize) -> KV {
    let table = TABLE.lock().unwrap();
    table[i]
}

fn main() {
    update_table(5, KV { k: 23, v: 35 });

    println!("{:?}", read_table(5));
}

请务必将lazy_static添加到您的Cargo.toml:

[dependencies]
lazy_static = "0.1.*"