从线程获取HashMap

问题描述 投票:0回答:1

我试图从一个线程获得一个值,在这种情况下是一个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需要共享这些东西。我仍然不知道如何让它工作。

multithreading rust
1个回答
2
投票

您可以使用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))
}

Playground

有关详细信息:我建议阅读The Rust Programming Language,特别是chapter on concurrency。在其中,您将了解Arc:特别是如果您想在线程之间共享数据。

© www.soinside.com 2019 - 2024. All rights reserved.