我有一个复杂的嵌套结构,它应该通过多线程处理高读/写。 评论:
use std::sync::RwLock;
use std::sync::atomic::AtomicBool;
use once_cell::sync::OnceCell;
#[derive(Default)]
struct Alien {
info: Info,
evil: AtomicBool,
}
#[derive(Default)]
struct Info {
address: String,
}
fn get_alien_instance() -> &'static Alien {
let alien = Alien::default();
static INSTANCE: OnceCell<Alien> = OnceCell::new();
INSTANCE.get_or_init(move || alien)
}
Alien
是具有多个字段和嵌套结构的父结构。将使用 &'static Alien
和内部可变性来改变 Alien
的 mut 字段。我正在讨论嵌套锁和可变性的问题。我想对 Info
结构使用单个(非嵌套)锁,但在其 impl
块内处理其突变。
一个奇怪的解决方案是在
Info
impl 本身中改变 Alien
字段。像这样的东西-
impl Alien {
fn update_info(&self) {
let mut info = self.info.write().unwrap();
info.address = "HEllo".to_string();
}
}
其他方法是用 Rwlock 包装所有内容。
#[derive(Default)]
struct Alien {
info: RwLock<Info>,
evil: AtomicBool,
}
#[derive(Default)]
struct Info {
address: RwLock<String>,
}
impl Info {
fn update_address(&self) {
let mut address = self.address.write().unwrap();
*address = String::from("Mars");
}
}
另一种方法是将
RwLockWriteGuard
传递给 Info
impl
。我不知道如何处理这个问题。在管理高读/写的同时,什么是理想的解决方案?
这对你有帮助吗?这就是我要做的,我认为当您将
Alien.info
作为 RwLock
时,您不需要在 Info 中使用 t RwLock
。
use std::sync::{OnceLock, RwLock};
#[derive(Default)]
struct Alien {
info: RwLock<Info>,
}
static INSTANCE: OnceLock<Alien> = OnceLock::new();
fn get_alien_instance() -> &'static Alien {
INSTANCE.get_or_init(move || Alien::default())
}
#[derive(Default)]
struct Info {
address: String,
}
impl Info {
pub fn update(&mut self, new: String) {
self.address = new;
}
}
fn main() {
std::thread::spawn(|| {
for s in ["Planet Foo", "Sun Bar", "Baz Galaxy"].iter().cycle().take(10){
get_alien_instance()
.info
.write()
.unwrap()
.update(s.to_string());
std::thread::sleep(std::time::Duration::from_millis(100));
}
});
for _ in 0..100 {
println!("Address: {}",get_alien_instance().info.read().unwrap().address);
std::thread::sleep(std::time::Duration::from_millis(10));
}
}