线程的Rust生命周期问题

时间:2018-12-22 03:58:44

标签: rust thread-safety lifetime

代码如下:

use std::collections::HashMap;
use std::thread;

type MAP = HashMap<String, String>;

fn handle_n_times(count: i32, map: &mut MAP) {
    for i in 0..count {
        thread::spawn(move || {
            map.insert(format!("key-{}", i), format!("value-{}", i));
        });
    }
}

fn main() {
    let mut map: MAP = MAP::new();
    handle_n_times(5, &mut map);
}

我无法编译:

error[E0621]: explicit lifetime required in the type of `map`
 --> src/main.rs:8:9
  |
6 | fn handle_n_times(count: i32, map: &mut MAP) {
  |                                    -------- help: add explicit lifetime `'static` to the type of `map`: `&'static mut std::collections::HashMap<std::string::String, std::string::String>`
7 |     for i in 0..count {
8 |         thread::spawn(move || {
  |         ^^^^^^^^^^^^^ lifetime `'static` required

它提供的提示(添加&'static)没有帮助。

问题1 :如何使此代码有效?

问题2 :问题1解决后,我想使用std::sync::Arc来使map成为线程安全的,Rust的处理方式是什么?

1 个答案:

答案 0 :(得分:1)

问题1:

将变量共享到新线程中不是线程安全的。在Rust中,您无法编译此代码。您可以使用Arc<Mutex<Map>>

使代码正常工作

问题2:

您需要按以下方式更改方法签名:

 handle_n_times(count: i32, arc_map: Arc<Mutex<Map>>)

如果要转移thread::spawn中的所有权,则需要克隆Arc值,然后再使用

将其发送到其他线程
 let clone_arc = arc_map.clone();

要将地图项插入地图时,需要通过Arc<Mutex>lockunwrap获取参考:

let map = clone_arc.lock().unwrap();

之后,您可以在没有明确的生存期要求的情况下致电map.insert

以下是完整的工作代码,为example