gpt4 book ai didi

multithreading - 对字段成员的Arc引用

转载 作者:行者123 更新时间:2023-11-29 08:22:26 24 4
gpt4 key购买 nike

我正在尝试生成一组给定的线程并让每个线程执行一个长时间运行的操作。我会将一个结构作为给定线程的内部状态传递给每个工作线程。所述结构的集合保存在一个向量中,它是 Master 结构的一部分。

编译器拒绝我将结构的内部成员传递给 Arc::new():

use std::thread;
use std::sync::Arc;

struct Worker {
name: String,
}

struct Master {
workers: Vec<Worker>,
}

impl Worker {
fn start(&self) {
println!("My name is {} and I'm working!", self.name);
thread::sleep_ms(100_000);
}
}

impl Master {
pub fn run_test(&mut self) {
for i in 0..10 {
self.workers.push(Worker {
name: String::new() + "Worker" + &i.to_string()
});
}
let mut data = Arc::new(self.workers);

for i in 0..10 {
let local_data = data.clone();
thread::spawn(move || {
local_data[i].start();
});
}

thread::sleep_ms(100_000);
}
}


fn main() {
let mut master = Master { workers: vec![] };
}

错误信息:

error[E0507]: cannot move out of borrowed content
--> <anon>:26:33
|
26 | let mut data = Arc::new(self.workers);
| ^^^^ cannot move out of borrowed content

我做错了什么?这是惯用的 Rust 吗?

最佳答案

欢迎使用所有权。

在 Rust 中,任何单个数据都有一个且恰好一个所有者。不要被 Rc 愚弄了和 Arc : 它们是位于单个(不可见)所有者之上的共享接口(interface)。

表达所有权的最简单方法是按值:

struct Master {
workers: Vec<Worker>
}

在这里,Master拥有 Vec<Worker>它本身拥有多个 Worker .

类似地,按值获取参数的函数(例如 fn new(t: T) -> Arc<T>)获得其参数的所有权。

这就是问题所在:

Arc::new(self.workers)

意味着你同时是:

  • 声称Masterworkers 的所有者
  • 声称Arcworkers 的所有者

鉴于一个且恰好一个所有者的规则,这显然是棘手的。


那么,您如何作弊并让单个数据拥有多个共同所有者?

嗯...使用RcArc !

struct Master {
workers: Arc<Vec<Worker>>
}

现在正在创建 data很简单:

let data = self.workers.clone();

这会创建一个新的 Arc (这只会增加引用计数)。


但这还不是全部。借用系统的核心原则是:Aliasing XOR Mutability

Arc是关于别名的,它防止了可变性。您不能将 worker 插入 self.workers不再!

有多种解决方案,比如推迟self.workers的初始化直到构建向量,然而最常见的是使用单元格或互斥锁,即 Rc<RefCell<T>>Arc<Mutex<T>> (或 Arc<RwLock<T>> )。

RefCellMutex是将借用检查从编译时移动到运行时的包装器。这提供了更多的灵 active ,但可能会导致运行时 panic 而不是编译时错误,因此最好作为最后的手段使用。

关于multithreading - 对字段成员的Arc引用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41770184/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com