是否有安全的方法将本地值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;
}
}
答案 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.*"