使用 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 立即被删除,强制线程在下一次迭代开始之前完成。

解决此问题后,您会遇到下一个问题,即 imtx 的寿命不够长。您需要 move 它们进入闭包:

thread::scoped(move || {})