使用 thread::scoped 时不并行编码 运行
Code not running in parallel when using thread::scoped
谁能解释一下为什么下面的代码不能运行并行?我想我不明白 thread::scoped
是如何工作的..
use std::thread;
use std::sync::{Arc, Mutex};
use std::time::Duration;
use std::old_io::timer;
fn main() {
let buf = Arc::new(Mutex::new(Vec::<String>::new()));
let res = test(buf);
println!("{:?}", *res.lock().unwrap());
}
fn test(buf: Arc<Mutex<Vec<String>>>) -> Arc<Mutex<Vec<String>>> {
let guards: Vec<_> = (0..3).map( |i| {
let mtx = buf.clone();
thread::scoped(|| {
println!("Thread: {}", i);
let mut res = mtx.lock().unwrap();
timer::sleep(Duration::seconds(5));
res.push(format!("thread {}", i));
});
}).collect();
buf
}
代码基于示例here,其中声明:
The scoped function takes one argument, a closure, indicated by the double bars ||. This closure is executed in a new thread created by scoped. The method is called scoped because it returns a 'join guard', which will automatically join the child thread when it goes out of scope. Because we collect these guards into a Vec, and that vector goes out of scope at the end of our program, our program will wait for every thread to finish before finishing.
谢谢
这是一个棘手的案例。问题是不起眼的分号。看看这个最小化的代码:
thread::scoped(|| {});
那个分号表示 collect
的结果不是 JoinGuard
的向量——它是 Vec<()>
!每个 JoinGuard
立即被删除,强制线程在下一次迭代开始之前完成。
解决此问题后,您会遇到下一个问题,即 i
和 mtx
的寿命不够长。您需要 move
它们进入闭包:
thread::scoped(move || {})
谁能解释一下为什么下面的代码不能运行并行?我想我不明白 thread::scoped
是如何工作的..
use std::thread;
use std::sync::{Arc, Mutex};
use std::time::Duration;
use std::old_io::timer;
fn main() {
let buf = Arc::new(Mutex::new(Vec::<String>::new()));
let res = test(buf);
println!("{:?}", *res.lock().unwrap());
}
fn test(buf: Arc<Mutex<Vec<String>>>) -> Arc<Mutex<Vec<String>>> {
let guards: Vec<_> = (0..3).map( |i| {
let mtx = buf.clone();
thread::scoped(|| {
println!("Thread: {}", i);
let mut res = mtx.lock().unwrap();
timer::sleep(Duration::seconds(5));
res.push(format!("thread {}", i));
});
}).collect();
buf
}
代码基于示例here,其中声明:
The scoped function takes one argument, a closure, indicated by the double bars ||. This closure is executed in a new thread created by scoped. The method is called scoped because it returns a 'join guard', which will automatically join the child thread when it goes out of scope. Because we collect these guards into a Vec, and that vector goes out of scope at the end of our program, our program will wait for every thread to finish before finishing.
谢谢
这是一个棘手的案例。问题是不起眼的分号。看看这个最小化的代码:
thread::scoped(|| {});
那个分号表示 collect
的结果不是 JoinGuard
的向量——它是 Vec<()>
!每个 JoinGuard
立即被删除,强制线程在下一次迭代开始之前完成。
解决此问题后,您会遇到下一个问题,即 i
和 mtx
的寿命不够长。您需要 move
它们进入闭包:
thread::scoped(move || {})