Dav*_*sen 3 concurrency multithreading ownership rust
我正在尝试编写一个程序,它生成一个后台线程,不断地将数据插入到某个集合中.同时,我想继续获取输入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()
}
Run Code Online (Sandbox Code Playgroud)
但是由于所有权的原因,这不起作用.
我还是Rust的新手,但这似乎应该是可行的.我只是找不到正确的Arc
s,Rc
s,Mutex
es等组合来包装我的数据.
首先,请阅读需要关于Rust的细胞和参考计数类型的整体解释.
这里有两个问题需要解决:
要分享所有权,最简单的解决方案是Arc
.它要求它的参数是Sync
(可以从多个线程安全地访问),可以Send
通过将其包装在一个Mutex
或多个中来实现任何类型RwLock
.
为了安全地获得混叠的可变性的存在,都Mutex
和RwLock
正常工作.如果您有多个读者,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...
}
}
}
Run Code Online (Sandbox Code Playgroud)
呼叫unwrap
是因为Mutex::lock
返回a Result
; Mutex
如果它被毒害,可能无法锁定它,这意味着当它被锁定时发生恐慌,因此其内容可能是垃圾.
归档时间: |
|
查看次数: |
342 次 |
最近记录: |