Multithreading 一个可变借用和多个不可变借用

Multithreading 一个可变借用和多个不可变借用,multithreading,concurrency,rust,ownership,Multithreading,Concurrency,Rust,Ownership,我正试图编写一个程序,生成一个后台线程,不断地将数据插入到某个集合中。同时,我希望不断从stdin获取输入,并检查该输入是否在线程操作的集合中 下面是一个简单的例子: use std::collections::HashSet; use std::thread; fn main() { let mut set: HashSet<String> = HashSet::new(); thread::spawn(move || { loop {

我正试图编写一个程序,生成一个后台线程,不断地将数据插入到某个集合中。同时,我希望不断从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()
}
使用std::collections::HashSet;
使用std::线程;
fn main(){
让mut set:HashSet=HashSet::new();
线程::生成(移动| |{
环路{
set.insert(“foo.to_string());
}
});
环路{
let input:String=get_input_from_stdin();
如果set.contains(&input){
//做点什么。。。
}
}
}
fn从\u stdin()获取\u输入\u->String{
字符串::new()
}
然而,这不起作用,因为所有权的东西

我还是个新手,但这似乎是可能的。我就是找不到合适的
Arc
s、
Rc
s、
Mutex
es等组合来包装我的数据。

首先,请阅读


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

  • 在线程之间共享所有权
  • 可变别名
  • 要共享所有权,最简单的解决方案是
    Arc
    。它要求其参数为
    Sync
    (可从多个线程安全访问),这可以通过将其包装在
    互斥体
    RwLock
    中,为任何
    发送
    类型实现

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

    因此,您的类型是:
    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
    返回一个
    结果
    ;如果互斥锁中毒,则可能无法锁定它,这意味着在锁定互斥锁时发生了恐慌,因此它的内容可能是垃圾。

    这可能会帮助您:由于无法包装任何类型的文档以获得
    同步,因此可能会出现重复;您需要包装一个
    Send
    类型。@Stefan:对!我甚至没有想到有人试图将一个非发送类型发送到另一个线程,但最好明确地说明这一点。