gpt4 book ai didi

multithreading - 一个可变借用和多个不可变借用

转载 作者:行者123 更新时间:2023-11-29 07:57:32 25 4
gpt4 key购买 nike

我正在尝试编写一个程序来生成一个后台线程,该线程不断地将数据插入某个集合。同时,我想继续从 stdin 获取输入并检查该输入是否在线程正在操作的集合中。

这是一个简单的例子:

use std::collections::HashSet;
use std::thread;

fn main() {
let mut set: HashSet<String> = HashSet::new();

thread::spawn(move || {
loop {
set.insert("foo".to_string());
}
});

loop {
let input: String = get_input_from_stdin();

if set.contains(&input) {
// Do something...
}
}
}

fn get_input_from_stdin() -> String {
String::new()
}

但是,由于所有权问题,这不起作用。

我对 Rust 还是个新手,但这似乎是可行的。我只是找不到 ArcRcMutexes 等的正确组合来包装我的数据。

最佳答案

首先,请阅读Need holistic explanation about Rust's cell and reference counted types


这里有两个问题需要解决:

  1. 在线程之间共享所有权,
  2. 可变别名。

要共享所有权,最简单的解决方案是 Arc 。它要求它的参数是 Sync(可从多个线程安全访问),这可以通过将其包装在 SendMutex 中来实现任何 RwLock 类型。

为了在存在可变性的情况下安全地获得别名,MutexRwLock 都可以工作。如果您有多个阅读器,RwLock 可能会有额外的性能优势。由于您只有一个阅读器,所以没有意义:让我们使用简单的 Mutex

因此,您的类型是:Arc<Mutex<HashSet<String>>>

下一个技巧是将值传递给闭包以在另一个线程中运行。该值已移动,因此您需要首先复制 Arc 然后传递该克隆,否则您已经移动了原始代码并且无法再访问它.

最后,访问数据需要经过借用和锁...

use std::sync::{Arc, Mutex};

fn main() {
let set = Arc::new(Mutex::new(HashSet::new()));

let clone = set.clone();
thread::spawn(move || {
loop {
clone.lock().unwrap().insert("foo".to_string());
}
});

loop {
let input: String = get_input_from_stdin();

if set.lock().unwrap().contains(&input) {
// Do something...
}
}
}

调用 unwrap 是因为 Mutex::lock 返回一个 Result ;如果 Mutex 中毒,则可能无法锁定它,这意味着它在锁定时发生了 panic ,因此其内容可能是垃圾。

关于multithreading - 一个可变借用和多个不可变借用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47092072/

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