我试图从一个线程获得一个值,在这种情况下是一个HashMap
。我将代码减少到以下(我最初尝试共享一个HashMap
containsig a Vec
):
use std::thread;
use std::sync::mpsc;
use std::sync::Mutex;
use std::sync::Arc;
use std::collections::HashMap;
fn main() {
let(tx, rx) = mpsc::channel();
let n_handle= thread::spawn( || {
tx.send(worker());
});
print!("{:?}", rx.recv().unwrap().into_inner().unwrap());
}
fn worker() -> Arc<Mutex<HashMap<String, i32>>>{
let result: HashMap<String, i32> = HashMap::new();
// some computation
Arc::from(Mutex::from(result))
}
Still Rust说:
std::sync::mpsc::Sender<std::sync::Arc<std::sync::Mutex<std::collections::HashMap<std::string::String, i32>>>>
不能安全地在线程之间共享
我读了一些关于将所有内容放入Arc<Mutex<..>>
的令人困惑的东西,我也尝试过这个值:
let result: HashMap<String, Arc<Mutex<i32>>> = HashMap::new();
任何人都可以向我指出一个文件,用HashMaps等值来解释mpsc :: channel的用法吗?我理解为什么它不起作用,因为特征Sync没有为HashMap实现,HashMap需要共享这些东西。我仍然不知道如何让它工作。
您可以使用mpsc
通道在线程之间传递值。
直到用thread::spawn
关键字标记你的move
,如下所示:
thread::spawn(move || {});
由于您没有使用move关键字对其进行标记,因此它不会将外部变量移动到线程范围中,而只是共享其引用。因此,您需要实现您使用的每个外部变量的Sync
特征。
mpsc::Sender
没有实现Sync
,这就是为什么你得到的错误无法在线程之间共享。
对于您的案例的解决方案将理想的是将发送者移动到线程范围内部,如下所示:
use std::collections::HashMap;
use std::sync::mpsc;
use std::sync::Arc;
use std::sync::Mutex;
use std::thread;
fn main() {
let (tx, rx) = mpsc::channel();
thread::spawn(move || {
let _ = tx.send(worker());
});
let arc = rx.recv().unwrap();
let hashmap_guard = arc.lock().unwrap();
print!(
"HashMap that retrieved from thread : {:?}",
hashmap_guard.get("Hello").unwrap()
);
}
fn worker() -> Arc<Mutex<HashMap<String, i32>>> {
let mut result: HashMap<String, i32> = HashMap::new();
result.insert("Hello".to_string(), 2);
// some computation
Arc::new(Mutex::new(result))
}
有关详细信息:我建议阅读The Rust Programming Language,特别是chapter on concurrency。在其中,您将了解Arc
:特别是如果您想在线程之间共享数据。