线程的 Rust 生命周期问题
Rust Lifetime Issue with Threads
代码如下:
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:
将变量共享到新线程中不是线程安全的。在 Rust 中你不能编译这段代码。您可以通过使用 Arc<Mutex<Map>>
使代码工作
问题 2:
您需要更改方法签名如下:
handle_n_times(count: i32, arc_map: Arc<Mutex<Map>>)
如果您要移动 thread::spawn
的所有权,您需要在使用
将其发送到其他线程之前克隆 Arc
值
let clone_arc = arc_map.clone();
当您想将项目插入地图时,您需要通过 lock
和 unwrap
:
从 Arc<Mutex>
获取参考
let map = clone_arc.lock().unwrap();
之后您可以调用 map.insert
,没有明确的生命周期要求。
这是完整的工作代码 example
代码如下:
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:
将变量共享到新线程中不是线程安全的。在 Rust 中你不能编译这段代码。您可以通过使用 Arc<Mutex<Map>>
问题 2:
您需要更改方法签名如下:
handle_n_times(count: i32, arc_map: Arc<Mutex<Map>>)
如果您要移动 thread::spawn
的所有权,您需要在使用
Arc
值
let clone_arc = arc_map.clone();
当您想将项目插入地图时,您需要通过 lock
和 unwrap
:
Arc<Mutex>
获取参考
let map = clone_arc.lock().unwrap();
之后您可以调用 map.insert
,没有明确的生命周期要求。
这是完整的工作代码 example