Function std::thread::spawn1.0.0[][src]

pub fn spawn<F, T>(f: F) -> JoinHandle<T> where
    F: FnOnce() -> T,
    F: Send + 'static,
    T: Send + 'static, 
Expand description

产生一个新线程,为其返回 JoinHandle

连接子句柄在被丢弃后将隐式分离子线程。在这种情况下,子线程可能会超过父线程 (除非父线程是主线程; 当主线程结束时,整个进程被终止)。 此外,联接句柄提供了 join 方法,可用于联接子线程。 如果子线程 panics,则 join 将返回包含给 panic! 的参数的 Err

这将使用 Builder 的默认参数创建一个线程,如果要指定栈大小或线程名称,请改用此 API。

如您在 spawn 的签名中所见,给 spawn 的闭包及其返回值都有两个约束,让我们对其进行解释:

  • 'static 约束意味着闭包及其返回值必须具有整个程序执行的生命周期。这样做的原因是,线程可以 detach 并使它们在其中创建的生命周期更长。 确实,如果线程及其扩展值可以超过调用者的生命周期,我们需要确保它们之后才有效,并且由于我们 无法 知道何时返回,因此需要使它们有效尽可能直到程序结束,因此是 'static 生命周期。

  • Send 约束是因为闭包将需要从产生它的线程中传递 by value 到新线程。它的返回值需要从新线程传递到 join 线程。 提醒一下,Send 标记 trait 表示从线程传递到线程是安全的。Sync 表示在每个线程之间传递引用是安全的。

Panics

如果操作系统无法创建线程,则为 Panics; 否则为 0。使用 Builder::spawn 从此类错误中恢复。

Examples

创建一个线程。

use std::thread;

let handler = thread::spawn(|| {
    // 线程代码
});

handler.join().unwrap();
Run

如模块文档中所述,线程通常是使用 channels 进行通信的,这是它通常的外观。

此示例还显示了如何使用 move,以便将值的所有权授予线程。

use std::thread;
use std::sync::mpsc::channel;

let (tx, rx) = channel();

let sender = thread::spawn(move || {
    tx.send("Hello, thread".to_owned())
        .expect("Unable to send on channel");
});

let receiver = thread::spawn(move || {
    let value = rx.recv().expect("Unable to receive from channel");
    println!("{}", value);
});

sender.join().expect("The sender thread has panicked");
receiver.join().expect("The receiver thread has panicked");
Run

线程也可以通过其 JoinHandle 返回一个值,您可以使用它进行异步计算 (不过 futures 可能更合适)。

use std::thread;

let computation = thread::spawn(|| {
    // 一些昂贵的计算。
    42
});

let result = computation.join().unwrap();
println!("{}", result);
Run