rust - Rust Arc 如何获取_mut 并在此之后恢复其他 Arc 副本的读取能力?
问题描述
我想知道如何更改内部的值Arc
,然后Arc
再次制作有效的其他副本。
use std::sync::Arc;
use std::thread;
use std::error::Error;
use std::io;
use std::time::Duration;
#[derive(Debug)]
struct El {
n: i64,
}
fn main() -> io::Result<()> {
let mut a = Arc::new(El{n: 5});
let b = Arc::clone(&a);
let th = thread::spawn(move || {
println!(r#"Hello, World!"#);
thread::sleep(Duration::from_millis(1000));
println!("{:?}", b);
});
let mut c = Arc::get_mut(&mut a).unwrap();
c.n = 10;
drop(c);
drop(a);
th.join().expect("some errors occured");
Ok(())
}
当突变已经完成并且指针被丢弃时,这将导致恐慌。如何解决?
解决方案
您想在一个线程中写入内容并Arc
在另一个线程中读取它。在 Rust 中,一个值要么是共享可读的,要么是独占可写的。具有多个参考的圆弧是共享的。
您可以通过使用内部可变性来解决此问题,例如 viaArc<Mutex<El>>
或Arc<RwLock<El>>
。Mutex
并RwLock
通过阻塞所有读取直到写入完成并在读取锁存在时阻塞所有写入来动态确保共享/排他约束。
例子:
fn main() -> io::Result<()> {
let a = Arc::new(Mutex::new(El{n: 5}));
let b = Arc::clone(&a);
let th = thread::spawn(move || {
println!(r#"Hello, World!"#);
thread::sleep(Duration::from_millis(1000));
println!("{:?}", b.lock().unwrap());
});
a.lock().unwrap().n = 10;
drop(a);
th.join().expect("some errors occured");
Ok(())
}
推荐阅读
- node.js - Vue.js + eslint。错误解析错误:意外的令牌@
- python - 文本文件中的 ANSI 转义颜色代码无法正确打印
- coq - 如何使用 ssreflect 序数索引元组
- c# - 是否可以在没有 Windows 商店且没有旁加载的情况下安装经过微软认证的 appx?
- r - 为超过 100% 的值调整风险表
- python - 在 Pandas 中将两行折叠为 1
- pdf - ghostpcl 9.53.2 linux 版本给出了 PCL 文件的错误;windows版本不适用于同一个文件
- r - 如何计算整齐的 data.table 中每个组的出现次数?
- spring-boot - Kubernetes:Tomcat在启用代理协议时抛出异常
- docker - 如何在 swarm 中创建新服务而不使用“docker stack”重新启动其他服务