Multithreading 一个可变借用和多个不可变借用
我正试图编写一个程序,生成一个后台线程,不断地将数据插入到某个集合中。同时,我希望不断从stdin获取输入,并检查该输入是否在线程操作的集合中 下面是一个简单的例子: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 {
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:对!我甚至没有想到有人试图将一个非发送类型发送到另一个线程,但最好明确地说明这一点。